Android中使用AsyncTask實現檔案下載以及進度更新提示

來源:互聯網
上載者:User

標籤:str   max   img   ima   即時   asynctask   執行個體   android   async   

Android提供了一個工具類:AsyncTask,它使建立需要與使用者介面互動的長時間啟動並執行任務變得更簡單。相對Handler來說AsyncTask更輕量級一些,適用於簡單的非同步處理,不需要藉助線程和Handter即可實現。AsyncTask是抽象類別。AsyncTask定義了三種泛型型別Params,Progress和Result:

Params啟動任務執行的輸入參數,比如,HTTP請求的URL。

Progress背景工作執行的百分比。

Result後台執行任務最終返回的結果,比如String。

通過用AsyncTask實現檔案下載以及進度更新提示的示範動圖:

本次真機示範的下載目錄為Download檔案夾,首先進入Download檔案夾,沒有圖片檔案,下載完成後,再次查看,可以看到本次示範的下載圖片

首先我們簡單介紹AsyncTask的執行步驟:

AsyncTask的執行分為四個步驟,每一步對應一個回調方法,我們需要的就是實現這些方法。

(1)首先定義一個類繼承AsyncTask

(2)實現AsyncTask中定義的下面一個或幾個方法

四個步驟方法分別為:

(1)onPreExecute():被UIThread調用,該方法用來做一些準備工作,如在介面上顯示一個進度條。

(2)dolnBackground(Params…):將在onPreExecute之後執行,運行在後台線程中。負責執行耗時工作。可以調用publishProgress方法來更新即時任務進度。

(3)onProgressUpdate(Progress…):在publishProgress方法被調用後,UIThread將調用該方法在介面上展示任務的進展情況,例如通過一個進度條進行展示。

(4)onPostExecute(Result):在dolnBackground執行完成後,onPostExecute方法將被UIThread調用,背景計算結果將通過該方法傳遞到UIThread。

效果實現程式碼範例: 第一步:Layout中Activity的布局檔案activity_main.xml
 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout 3     xmlns:android="http://schemas.android.com/apk/res/android" 4     xmlns:tools="http://schemas.android.com/tools" 5     android:id="@+id/activity_main" 6     android:layout_width="match_parent" 7     android:layout_height="match_parent" 8     android:orientation="vertical" 9     tools:context="com.example.administrator.asynctask.MainActivity">10     <TextView11         android:id="@+id/tv"12         android:layout_width="match_parent"13         android:layout_height="wrap_content"14         android:text="panhouye!"15         android:textSize="20sp"/>16     <ProgressBar17         android:id="@+id/progress"18         android:layout_width="match_parent"19         android:layout_height="wrap_content"20         style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"21         android:visibility="visible"/>22     <Button23         android:layout_width="match_parent"24         android:layout_height="wrap_content"25         android:onClick="image"26         android:text="下載圖片"/>27 </LinearLayout>
第二步:Java實現代碼MainActivity.java檔案
 1 import android.os.AsyncTask; 2 import android.os.Environment; 3 import android.support.v7.app.AppCompatActivity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.ProgressBar; 7 import android.widget.TextView; 8 import java.io.BufferedInputStream; 9 import java.io.BufferedOutputStream;10 import java.io.File;11 import java.io.FileOutputStream;12 import java.net.HttpURLConnection;13 import java.net.URL;14 /**15  * Created by panchengjia on 2016/12/19.16  */17 public class MainActivity extends AppCompatActivity {18 //聲明publishProgress的更新標記19     private static final int PROGRESS_MAX = 0X1;20     private static final int UPDATE = 0X2;21     private TextView tv;22     ProgressBar progress;23     int contentLen;//聲明要下載的檔案總長24     @Override25     protected void onCreate(Bundle savedInstanceState) {26         super.onCreate(savedInstanceState);27         setContentView(R.layout.activity_main);28         tv = (TextView) findViewById(R.id.tv);29         progress = (ProgressBar) findViewById(R.id.progress);30     }31     public void image(View view){32     //啟用AsyncTask,傳入需要執行的內容(圖片地址)33         new DownLoad().execute("http://cdnq.duitang.com/uploads/item/201402/22/20140222115440_jWNmx.thumb.700_0.jpeg");34     }35     class DownLoad extends AsyncTask<String,Integer,String>{36     //在執行實際的後台操作前被UI Thread調用37         @Override38         protected void onPreExecute() {39             super.onPreExecute();40             //準備下載前的初始進度41             progress.setProgress(0);42         }43     //在onPreExecute執行,該方法運行在後台線程中44         @Override45         protected String doInBackground(String... params) {46             try {47                 URL url = new URL(params[0]);48                 //擷取串連49                 HttpURLConnection connection = (HttpURLConnection) url.openConnection();50                 //擷取下載檔案的大小51                  contentLen = connection.getContentLength();52                 //根據下載檔案大小設定進度條最大值(使用標記區別即時進度更新)53                 publishProgress(PROGRESS_MAX,contentLen);54                 //迴圈下載(邊讀取邊存入)55                 BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());56                 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new57                         File(Environment.getExternalStorageDirectory()+"/Download/ss.jpg")));58                 int len =-1;59                 byte[] bytes = new byte[1024];60                 while((len=bis.read(bytes))!=-1){61                     bos.write(bytes,0,len);62                     bos.flush();63                     //即時更新下載進度(使用標記區別最大值)64                     publishProgress(UPDATE,len);65                     //示範下載的圖片太小,網速太快,休眠300毫秒,方便大家觀察66                     Thread.sleep(300);67                 }68                 bos.close();69                 bis.close();70             } catch (Exception e) {71                 e.printStackTrace();72             }73             return "下載完成";74         }75     //在publishProgress被調用後,UI thread會調用這個方法76         @Override77         protected void onProgressUpdate(Integer... values) {78             super.onProgressUpdate(values);79             switch (values[0]){80                 case PROGRESS_MAX:81                     progress.setMax(values[1]);82                     break;83                 case UPDATE:84                     progress.incrementProgressBy(values[1]);85                     //擷取下載進度百分比並更新textview86                     int i=(progress.getProgress()*100)/contentLen;87                     tv.setText("下載進度為:"+i+"%");88                     break;89             }90         }91     //doInBackground方法執行完後被UI thread執行92         @Override93         protected void onPostExecute(String s) {94             super.onPostExecute(s);95             progress.setVisibility(View.GONE);96             tv.setText(s);97         }98     }99 }
最後強調一下AsyncTask的設計準則:

(1)AsyncTask的執行個體必須在UlThread中建立。

(2)execute方法必須在UlThread中調用。

(3)不要手動的調用onPreExecute(),onPostExecute(Result),dolnBackground(Params…),onProgressUpdate(Progress…)這幾個方法。

(4)該Task只能被執行一次,否則多次調用時將會出現異常。

(5)AsyncTask不能完全取代線程,在一些邏輯較為複雜或者需要在後台反覆執行的邏輯就可能需要線程來實現了。

 

Android中使用AsyncTask實現檔案下載以及進度更新提示

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.