AsyncTask——非同步任務
阿新 • • 發佈:2019-01-10
一、定義:
Android UI執行緒是不安全的,如果想在子執行緒進行UI操作,就要用到Android的非同步訊息處理機制,除了Handler之外,還有一個AsyncTask也能夠實現。
二、AsyncTask用法
2.1、三個引數
要使用AsyncTask首先建立一個類,並繼承它,同時需要指定他的三個泛型引數。
public class DownloadAsyncTask extends AsyncTask<Void, Integer, Integer> {
}
1、Params(Void)
在執行後臺任務時需要傳入的引數。
2、Progress(Integer)
後臺任務需要向外傳遞任務程序時的引數型別。
3、Result(Integer)
後臺任務執行完,需要提交給UI執行緒所處理的資料型別。
當然這三個引數如果有不需要的可以定義為Void。
2.2 四個方法
- Void onPreExecute()
在執行後臺任務之前,需要再UI執行緒中進行的一些設定操作,比如初始化ProgressBar等。
- doInBackground()
執行後臺耗時任務。
- Void onProgressUpdate()
當後臺任務執行過程中需要向外傳遞任務進度時,通過呼叫publishProgress()即可將程序引數傳遞給此方法。一般在此方法中進行任務進度的顯示的相關操作。
- onPostExecute()
將後臺任務結束後傳遞出來的引數在此方法中進行UI介面的更新操作。
三、例項參考
本例實現了將一段網路視訊下載到手機SD卡上的任務。
package com.example.pc.externalstoragetest; import android.annotation.SuppressLint; import android.os.AsyncTask; import android.os.Environment; import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; /** * Created by pc on 2018/6/6. */ public class DownloadAsyncTask extends AsyncTask<Void, Integer, Integer> { private ProgressBar pb; private TextView showProgressNub; public DownloadAsyncTask(ProgressBar pb,TextView showProgressNub) { this.pb = pb; this.showProgressNub=showProgressNub; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Integer doInBackground(Void... voids) { //在SD卡上新建一個名叫:dahuangfeng.mp4的檔案 File f=new File(Environment.getExternalStorageDirectory(),"dahuangfeng.mp4"); //如果不存在則建立 if(!f.exists()){ try { f.createNewFile(); //獲取該檔案的輸出流 OutputStream os=new FileOutputStream(f); //建立一個URL的網路視訊連線 URL url=new URL("http://vt1.doubanio.com/201806051925/5a95ce9e62a5473be84dfbaa1b69302b/view/movie/M/402300072.mp4"); //通過URL.openConnection()獲取 HttpURLConnection HttpURLConnection conn= (HttpURLConnection) url.openConnection(); //設定請求方法為GET conn.setRequestMethod("GET"); //設定請求時間 conn.setReadTimeout(5000); //獲取輸入流 InputStream is=conn.getInputStream(); //獲取檔案總大小 long total_lenth=conn.getContentLength(); //讀取輸入流中的資料,並寫入到SD卡dahuangfeng.mp4的檔案中 byte[] b=new byte[1024]; int length=0; int current_lenth=0; while((length=is.read(b))!=-1){ os.write(b,0,length); //當前已讀檔案的大小 current_lenth+=length; //獲取當前進度 float progress= (current_lenth/(float)total_lenth)*100000; int value= (int) progress; //將進度資料傳遞給UI執行緒 publishProgress(value); } System.out.println("..........下載結束....."); os.flush(); is.close(); os.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return null; } @SuppressLint("NewApi") @Override protected void onProgressUpdate(Integer... values) { pb.setMax(100); pb.setMin(0); //設定progressBar的當前進度 pb.setProgress(values[0]); pb.setVisibility(View.VISIBLE); //在Textview中顯示進度數字 showProgressNub.setText(pb.getProgress()+"%"); super.onProgressUpdate(values); } @Override protected void onPostExecute(Integer file) { super.onPostExecute(file); } }
效果圖
錄製軟體有點問題,應該是點選按鈕,就會立即下載。