Android中使用AsyncTask實現(xiàn)文件下載以及進度更新提示
Android提供了一個工具類:AsyncTask,它使創(chuàng)建需要與用戶界面交互的長時間運行的任務(wù)變得更簡單。相對Handler來說AsyncTask更輕量級一些,適用于簡單的異步處理,不需要借助線程和Handter即可實現(xiàn)。AsyncTask是抽象類。AsyncTask定義了三種泛型類型Params,Progress和Result:
Params啟動任務(wù)執(zhí)行的輸入?yún)?shù),比如,HTTP請求的URL。
Progress后臺任務(wù)執(zhí)行的百分比。
Result后臺執(zhí)行任務(wù)最終返回的結(jié)果,比如String。
通過用AsyncTask實現(xiàn)文件下載以及進度更新提示的演示動圖:
本次真機演示的下載目錄為Download文件夾,首先進入Download文件夾,沒有圖片文件,下載完成后,再次查看,可以看到本次演示的下載圖片

首先我們簡單介紹AsyncTask的執(zhí)行步驟:
AsyncTask的執(zhí)行分為四個步驟,每一步對應(yīng)一個回調(diào)方法,我們需要的就是實現(xiàn)這些方法。
(1)首先定義一個類繼承AsyncTask
(2)實現(xiàn)AsyncTask中定義的下面一個或幾個方法
四個步驟方法分別為:
(1)onPreExecute():被UIThread調(diào)用,該方法用來做一些準備工作,如在界面上顯示一個進度條。
(2)dolnBackground(Params…):將在onPreExecute之后執(zhí)行,運行在后臺線程中。負責執(zhí)行耗時工作。可以調(diào)用publishProgress方法來更新實時任務(wù)進度。
(3)onProgressUpdate(Progress…):在publishProgress方法被調(diào)用后,UIThread將調(diào)用該方法在界面上展示任務(wù)的進展情況,例如通過一個進度條進行展示。
(4)onPostExecute(Result):在dolnBackground執(zhí)行完成后,onPostExecute方法將被UIThread調(diào)用,后臺的計算結(jié)果將通過該方法傳遞到UIThread。
效果實現(xiàn)代碼示例:
第一步:Layout中Activity的布局文件activity_main.xml
<?xml version="." encoding="utf-"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.asynctask.MainActivity">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="panhouye!"
android:textSize="sp"/>
<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:visibility="visible"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="image"
android:text="下載圖片"/>
</LinearLayout>
第二步:Java實現(xiàn)代碼MainActivity.java文件
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created by panchengjia on //.
*/
public class MainActivity extends AppCompatActivity {
//聲明publishProgress的更新標記
private static final int PROGRESS_MAX = X;
private static final int UPDATE = X;
private TextView tv;
ProgressBar progress;
int contentLen;//聲明要下載的文件總長
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
progress = (ProgressBar) findViewById(R.id.progress);
}
public void image(View view){
//啟用AsyncTask,傳入需要執(zhí)行的內(nèi)容(圖片地址)
new DownLoad().execute("http://cdnq.duitang.com/uploads/item///_jWNmx.thumb._.jpeg");
}
class DownLoad extends AsyncTask<String,Integer,String>{
//在執(zhí)行實際的后臺操作前被UI Thread調(diào)用
@Override
protected void onPreExecute() {
super.onPreExecute();
//準備下載前的初始進度
progress.setProgress();
}
//在onPreExecute執(zhí)行,該方法運行在后臺線程中
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[]);
//獲取連接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//獲取下載文件的大小
contentLen = connection.getContentLength();
//根據(jù)下載文件大小設(shè)置進度條最大值(使用標記區(qū)別實時進度更新)
publishProgress(PROGRESS_MAX,contentLen);
//循環(huán)下載(邊讀取邊存入)
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new
File(Environment.getExternalStorageDirectory()+"/Download/ss.jpg")));
int len =-;
byte[] bytes = new byte[];
while((len=bis.read(bytes))!=-){
bos.write(bytes,,len);
bos.flush();
//實時更新下載進度(使用標記區(qū)別最大值)
publishProgress(UPDATE,len);
//演示下載的圖片太小,網(wǎng)速太快,休眠毫秒,方便大家觀察
Thread.sleep();
}
bos.close();
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return "下載完成";
}
//在publishProgress被調(diào)用后,UI thread會調(diào)用這個方法
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
switch (values[]){
case PROGRESS_MAX:
progress.setMax(values[]);
break;
case UPDATE:
progress.incrementProgressBy(values[]);
//獲取下載進度百分比并更新textview
int i=(progress.getProgress()*)/contentLen;
tv.setText("下載進度為:"+i+"%");
break;
}
}
//doInBackground方法執(zhí)行完后被UI thread執(zhí)行
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progress.setVisibility(View.GONE);
tv.setText(s);
}
}
}
最后強調(diào)一下AsyncTask的設(shè)計準則:
(1)AsyncTask的實例必須在UlThread中創(chuàng)建。
(2)execute方法必須在UlThread中調(diào)用。
(3)不要手動的調(diào)用onPreExecute(),onPostExecute(Result),dolnBackground(Params…),onProgressUpdate(Progress…)這幾個方法。
(4)該Task只能被執(zhí)行一次,否則多次調(diào)用時將會出現(xiàn)異常。
(5)AsyncTask不能完全取代線程,在一些邏輯較為復雜或者需要在后臺反復執(zhí)行的邏輯就可能需要線程來實現(xiàn)了。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定義View實現(xiàn)繪制虛線的方法詳解
這篇文章主要給大家介紹了Android自定義View實現(xiàn)繪制虛線的方法,在繪制過程中走了一些彎路才實現(xiàn)了虛線的效果,所以想著總結(jié)分享出來,方便有需要的朋友和自己在需要的時候參考學習,下面來一起看看吧。2017-04-04
Convert WebP to PNG using java
本文主要介紹Convert WebP to PNG using java,這里對 WebP 做了詳細說明,并講解Linux 環(huán)境下WebP 轉(zhuǎn)png格式的示例,有興趣的小伙伴可以參考下2016-08-08
Android開發(fā)筆記之:用Enum(枚舉類型)取代整數(shù)集的應(yīng)用詳解
本篇文章是對Android中用Enum(枚舉類型)取代整數(shù)集的應(yīng)用進行了詳細的分析介紹,需要的朋友參考下2013-05-05
Android使用GridView實現(xiàn)日歷功能示例(詳細代碼)
本篇文章主要介紹了Android使用GridView實現(xiàn)日歷功能示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考,一起跟隨小編過來看看吧2017-01-01
Android 簡單的彈出框(在屏幕中間,傳string[],根據(jù)內(nèi)容框框大小自適應(yīng))
這篇文章主要介紹了Android 簡單的彈出框(在屏幕中間,傳string[],根據(jù)內(nèi)容框框大小自適應(yīng)),需要的朋友可以參考下2017-04-04
Android編程中出現(xiàn)The connection to adb is down問題的解決方法
這篇文章主要介紹了Android編程中出現(xiàn)The connection to adb is down問題的解決方法,涉及Android進程與服務(wù)的相關(guān)操作技巧,需要的朋友可以參考下2015-12-12

