在Android應(yīng)用中利用異步任務(wù)實(shí)現(xiàn)一個(gè)進(jìn)度條下載功能?很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
成都創(chuàng)新互聯(lián)公司的客戶來自各行各業(yè),為了共同目標(biāo),我們在工作上密切配合,從創(chuàng)業(yè)型小企業(yè)到企事業(yè)單位,感謝他們對我們的要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。專業(yè)領(lǐng)域包括網(wǎng)站設(shè)計(jì)制作、網(wǎng)站設(shè)計(jì)、電商網(wǎng)站開發(fā)、微信營銷、系統(tǒng)平臺(tái)開發(fā)。
為什么要用異步任務(wù)?
在Android中只有在主線程才能對ui進(jìn)行更新操作,而其它線程不能直接對ui進(jìn)行操作
android本身是一個(gè)多線程的操作系統(tǒng),我們不能把所有的操作都放在主線程中操作 ,比如一些耗時(shí)操作。如果放在主線程中 會(huì)造成阻塞 而當(dāng)阻塞事件過長時(shí) 系統(tǒng)會(huì)拋出anr異常。所以我們要使用異步任務(wù)。android為我們提供了一個(gè)封裝好的組件asynctask。
AsyncTask可以在子線程中更新ui,封裝簡化了異步操作。適用于簡單的異步處理。如果多個(gè)后臺(tái)任務(wù)時(shí)就要使用Handler了 在這里就不再說明。
AsyncTask通常用于被繼承。AsyncTask定義了三種泛型類型
繼承AsyncTask后要重寫的方法有:
doInBackgroud:必須重寫,異步執(zhí)行后臺(tái)線程要完成的任務(wù),耗時(shí)任務(wù)要寫在這里,并且在這里不能操作ui??梢哉{(diào)用 publishProgress方法來更新實(shí)時(shí)的任務(wù)進(jìn)度
onPreExecute:執(zhí)行耗時(shí)操作前調(diào)用,可以完成一些初始化操作
onPostExecute:在doInBackground 執(zhí)行完成后,主線程調(diào)用此方法,可以在此方法中操作ui
onProgressUpdate:在doInBackgroud方法中調(diào)用publishProgress方法,更新任務(wù)的執(zhí)行進(jìn)度后 就會(huì)調(diào)用這個(gè)方法
下面通過一個(gè)實(shí)例來了解AsyncTask
首先附上運(yùn)行結(jié)果
布局文件:
MainActivity
package com.example.asynctask; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URLConnection; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity implements OnClickListener{ private ImageView image; private ProgressDialog progress; private Button btn_download; private static String URL="http://img4.imgtn.bdimg.com/it/u=1256159061,743487979&fm=21&gp=0.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image=(ImageView) findViewById(R.id.iv_image); btn_download=(Button) findViewById(R.id.btn_download); progress=new ProgressDialog(this); progress.setIcon(R.drawable.ic_launcher); progress.setTitle("提示信息"); progress.setMessage("正在下載,請稍候..."); progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); btn_download.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub new MyAsyncTask().execute(URL); } /* * String*********對應(yīng)我們的URL類型 * Integer********進(jìn)度條的進(jìn)度值 * BitMap*********異步任務(wù)完成后返回的類型 * */ class MyAsyncTask extends AsyncTask{ //執(zhí)行異步任務(wù)(doInBackground)之前執(zhí)行,并且在ui線程中執(zhí)行 @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); if(image!=null){ image.setVisibility(View.GONE); } //開始下載 對話框進(jìn)度條顯示 progress.show(); progress.setProgress(0); } @Override protected Bitmap doInBackground(String... params) { // TODO Auto-generated method stub //params是一個(gè)可變長的數(shù)組 在這里我們只傳進(jìn)來了一個(gè)url String url=params[0]; Bitmap bitmap=null; URLConnection connection; InputStream is;//用于獲取數(shù)據(jù)的輸入流 ByteArrayOutputStream bos;//可以捕獲內(nèi)存緩沖區(qū)的數(shù)據(jù),轉(zhuǎn)換成字節(jié)數(shù)組。 int len; float count=0,total;//count為圖片已經(jīng)下載的大小 total為總大小 try { //獲取網(wǎng)絡(luò)連接對象 connection=(URLConnection) new java.net.URL(url).openConnection(); //獲取當(dāng)前頁面的總長度 total=(int)connection.getContentLength(); //獲取輸入流 is=connection.getInputStream(); bos=new ByteArrayOutputStream(); byte []data=new byte[1024]; while((len=is.read(data))!=-1){ count+=len; bos.write(data,0,len); //調(diào)用publishProgress公布進(jìn)度,最后onProgressUpdate方法將被執(zhí)行 publishProgress((int)(count/total*100)); //為了顯示出進(jìn)度 人為休眠0.5秒 Thread.sleep(500); } bitmap=BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().length); is.close(); bos.close(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return bitmap; } //在ui線程中執(zhí)行 可以操作ui @Override protected void onPostExecute(Bitmap bitmap) { // TODO Auto-generated method stub super.onPostExecute(bitmap); //下載完成 對話框進(jìn)度條隱藏 progress.cancel(); image.setImageBitmap(bitmap); image.setVisibility(View.VISIBLE); } /* * 在doInBackground方法中已經(jīng)調(diào)用publishProgress方法 更新任務(wù)的執(zhí)行進(jìn)度后 * 調(diào)用這個(gè)方法 實(shí)現(xiàn)進(jìn)度條的更新 * */ @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); progress.setProgress(values[0]); } } }
最后不要忘記在AndroidManifest文件中配置網(wǎng)絡(luò)訪問權(quán)限
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。