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

首先我們簡(jiǎn)單介紹AsyncTask的執(zhí)行步驟:
AsyncTask的執(zhí)行分為四個(gè)步驟,每一步對(duì)應(yīng)一個(gè)回調(diào)方法,我們需要的就是實(shí)現(xiàn)這些方法。
(1)首先定義一個(gè)類繼承AsyncTask
(2)實(shí)現(xiàn)AsyncTask中定義的下面一個(gè)或幾個(gè)方法
四個(gè)步驟方法分別為:
(1)onPreExecute():被UIThread調(diào)用,該方法用來(lái)做一些準(zhǔn)備工作,如在界面上顯示一個(gè)進(jìn)度條。
(2)dolnBackground(Params…):將在onPreExecute之后執(zhí)行,運(yùn)行在后臺(tái)線程中。負(fù)責(zé)執(zhí)行耗時(shí)工作。可以調(diào)用publishProgress方法來(lái)更新實(shí)時(shí)任務(wù)進(jìn)度。
(3)onProgressUpdate(Progress…):在publishProgress方法被調(diào)用后,UIThread將調(diào)用該方法在界面上展示任務(wù)的進(jìn)展情況,例如通過(guò)一個(gè)進(jìn)度條進(jìn)行展示。
(4)onPostExecute(Result):在dolnBackground執(zhí)行完成后,onPostExecute方法將被UIThread調(diào)用,后臺(tái)的計(jì)算結(jié)果將通過(guò)該方法傳遞到UIThread。
效果實(shí)現(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實(shí)現(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的更新標(biāo)記
private static final int PROGRESS_MAX = X;
private static final int UPDATE = X;
private TextView tv;
ProgressBar progress;
int contentLen;//聲明要下載的文件總長(zhǎng)
@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í)行實(shí)際的后臺(tái)操作前被UI Thread調(diào)用
@Override
protected void onPreExecute() {
super.onPreExecute();
//準(zhǔn)備下載前的初始進(jìn)度
progress.setProgress();
}
//在onPreExecute執(zhí)行,該方法運(yùn)行在后臺(tái)線程中
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[]);
//獲取連接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//獲取下載文件的大小
contentLen = connection.getContentLength();
//根據(jù)下載文件大小設(shè)置進(jìn)度條最大值(使用標(biāo)記區(qū)別實(shí)時(shí)進(jìn)度更新)
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();
//實(shí)時(shí)更新下載進(jìn)度(使用標(biāo)記區(qū)別最大值)
publishProgress(UPDATE,len);
//演示下載的圖片太小,網(wǎng)速太快,休眠毫秒,方便大家觀察
Thread.sleep();
}
bos.close();
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return "下載完成";
}
//在publishProgress被調(diào)用后,UI thread會(huì)調(diào)用這個(gè)方法
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
switch (values[]){
case PROGRESS_MAX:
progress.setMax(values[]);
break;
case UPDATE:
progress.incrementProgressBy(values[]);
//獲取下載進(jìn)度百分比并更新textview
int i=(progress.getProgress()*)/contentLen;
tv.setText("下載進(jìn)度為:"+i+"%");
break;
}
}
//doInBackground方法執(zhí)行完后被UI thread執(zhí)行
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progress.setVisibility(View.GONE);
tv.setText(s);
}
}
}
最后強(qiáng)調(diào)一下AsyncTask的設(shè)計(jì)準(zhǔn)則:
(1)AsyncTask的實(shí)例必須在UlThread中創(chuàng)建。
(2)execute方法必須在UlThread中調(diào)用。
(3)不要手動(dòng)的調(diào)用onPreExecute(),onPostExecute(Result),dolnBackground(Params…),onProgressUpdate(Progress…)這幾個(gè)方法。
(4)該Task只能被執(zhí)行一次,否則多次調(diào)用時(shí)將會(huì)出現(xiàn)異常。
(5)AsyncTask不能完全取代線程,在一些邏輯較為復(fù)雜或者需要在后臺(tái)反復(fù)執(zhí)行的邏輯就可能需要線程來(lái)實(shí)現(xiàn)了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定義View實(shí)現(xiàn)繪制虛線的方法詳解
這篇文章主要給大家介紹了Android自定義View實(shí)現(xiàn)繪制虛線的方法,在繪制過(guò)程中走了一些彎路才實(shí)現(xiàn)了虛線的效果,所以想著總結(jié)分享出來(lái),方便有需要的朋友和自己在需要的時(shí)候參考學(xué)習(xí),下面來(lái)一起看看吧。2017-04-04
Android倒計(jì)時(shí)神器(CountDownTimer)
這篇文章主要為大家詳細(xì)介紹了Android倒計(jì)時(shí)神器CountDownTimer,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01
Convert WebP to PNG using java
本文主要介紹Convert WebP to PNG using java,這里對(duì) WebP 做了詳細(xì)說(shuō)明,并講解Linux 環(huán)境下WebP 轉(zhuǎn)png格式的示例,有興趣的小伙伴可以參考下2016-08-08
Android開發(fā)筆記之:用Enum(枚舉類型)取代整數(shù)集的應(yīng)用詳解
本篇文章是對(duì)Android中用Enum(枚舉類型)取代整數(shù)集的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android Service啟動(dòng)過(guò)程完整分析
這篇文章主要為大家詳細(xì)分析了Android Service啟動(dòng)完整過(guò)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
Android使用GridView實(shí)現(xiàn)日歷功能示例(詳細(xì)代碼)
本篇文章主要介紹了Android使用GridView實(shí)現(xiàn)日歷功能示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧2017-01-01
Android 簡(jiǎn)單的彈出框(在屏幕中間,傳string[],根據(jù)內(nèi)容框框大小自適應(yīng))
這篇文章主要介紹了Android 簡(jiǎn)單的彈出框(在屏幕中間,傳string[],根據(jù)內(nèi)容框框大小自適應(yīng)),需要的朋友可以參考下2017-04-04
Android編程中出現(xiàn)The connection to adb is down問(wèn)題的解決方法
這篇文章主要介紹了Android編程中出現(xiàn)The connection to adb is down問(wèn)題的解決方法,涉及Android進(jìn)程與服務(wù)的相關(guān)操作技巧,需要的朋友可以參考下2015-12-12

