Android中使用AsyncTask實(shí)現(xiàn)下載文件動態(tài)更新進(jìn)度條功能
1. 泛型
AysncTask<Params, Progress, Result>
Params:啟動任務(wù)時傳入的參數(shù),通過調(diào)用asyncTask.execute(param)方法傳入。
Progress:后臺任務(wù)執(zhí)行的進(jìn)度,若不用顯示進(jìn)度條,則不需要指定。
Result:后臺任務(wù)結(jié)束時返回的結(jié)果。
2. 重要方法
doInBackground(Params... params):必須重寫的方法,后臺任務(wù)就在這里執(zhí)行,會開啟一個新的線程。params為啟動任務(wù)時傳入的參數(shù),參數(shù)個數(shù)不定。
onPreExecute():在主線程中調(diào)用,在后臺任務(wù)開啟前的操作在這里進(jìn)行,例如顯示一個進(jìn)度條對話框。
onPostExecute(Result result):當(dāng)后臺任務(wù)結(jié)束后,在主線程中調(diào)用,處理doInBackground()方法返回的結(jié)果。
onProgressUpdate(Progress... values):當(dāng)在doInBackground()中調(diào)用publishProgress(Progress... values)時,返回主線程中調(diào)用,這里的參數(shù)個數(shù)也是不定的。
onCancelled():取消任務(wù)。

3. 注意事項(xiàng)
(1)execute()方法必須在主線程中調(diào)用;
(2)AsyncTask實(shí)例必須在主線程中創(chuàng)建;
(3)不要手動調(diào)用doInBackground()、onPreExecute()、onPostExecute()、onProgressUpdate()方法;
(4)注意防止內(nèi)存泄漏,在doInBackground()方法中若出現(xiàn)對Activity的強(qiáng)引用,可能會造成內(nèi)存泄漏。
4. 下載文件動態(tài)更新進(jìn)度條(未封裝)
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
tools:context="com.studying.asynctaskdemo.MainActivity">
<ProgressBar
android:id="@+id/progressBar"
style="?android:progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="0" />
<Button
android:id="@+id/download"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:text="@string/start_btn" />
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/waiting" />
</LinearLayout>
Activity:
public class MainActivity extends Activity {
private static final String FILE_NAME = "test.pdf";//下載文件的名稱
private static final String PDF_URL = "http://clfile.imooc.com/class/assist/118/1328281/AsyncTask.pdf";
private ProgressBar mProgressBar;
private Button mDownloadBtn;
private TextView mStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
setListener();
}
private void initView() {
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mDownloadBtn = (Button) findViewById(R.id.download);
mStatus = (TextView) findViewById(R.id.status);
}
private void setListener() {
mDownloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//AsyncTask實(shí)例必須在主線程創(chuàng)建
DownloadAsyncTask asyncTask = new DownloadAsyncTask();
asyncTask.execute(PDF_URL);
}
});
}
/**
* 泛型:
* String:傳入?yún)?shù)為文件下載地址
* Integer:下載過程中更新ProgressBar的進(jìn)度
* Boolean:是否下載成功
*/
private class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
private String mFilePath;//下載文件的保存路徑
@Override
protected Boolean doInBackground(String... params) {
if (params != null && params.length > 0) {
String pdfUrl = params[0];
try {
URL url = new URL(pdfUrl);
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
int contentLength = urlConnection.getContentLength();//獲取內(nèi)容總長度
mFilePath = Environment.getExternalStorageDirectory() + File.separator + FILE_NAME;
//若存在同名文件則刪除
File pdfFile = new File(mFilePath);
if (pdfFile.exists()) {
boolean result = pdfFile.delete();
if (!result) {
return false;
}
}
int downloadSize = 0;//已經(jīng)下載的大小
byte[] bytes = new byte[1024];
int length = 0;
OutputStream out = new FileOutputStream(mFilePath);
while ((length = in.read(bytes)) != -1) {
out.write(bytes, 0, length);
downloadSize += length;
publishProgress(downloadSize / contentLength * 100);
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
} else {
return false;
}
return true;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mDownloadBtn.setText("下載中");
mDownloadBtn.setEnabled(false);
mStatus.setText("下載中");
mProgressBar.setProgress(0);
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
mDownloadBtn.setText("下載完成");
mStatus.setText(aBoolean ? "下載完成" + mFilePath : "下載失敗");
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (values != null && values.length > 0) {
mProgressBar.setProgress(values[0]);
}
}
}
}
5. 下載文件動態(tài)更新進(jìn)度條(封裝)
Activity:
public class MainActivity extends Activity {
private static final String FILE_NAME = "test.pdf";
private static final String PDF_URL = "http://clfile.imooc.com/class/assist/118/1328281/AsyncTask.pdf";
private ProgressBar mProgressBar;
private Button mDownloadBtn;
private TextView mStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
setListener();
}
private void initView() {
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mDownloadBtn = (Button) findViewById(R.id.download);
mStatus = (TextView) findViewById(R.id.status);
}
private void setListener() {
mDownloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String localPath = Environment.getExternalStorageDirectory() + File.separator + FILE_NAME;
DownloadHelper.download(PDF_URL, localPath, new DownloadHelper.OnDownloadListener() {
@Override
public void onStart() {
mDownloadBtn.setText("下載中");
mDownloadBtn.setEnabled(false);
mStatus.setText("下載中");
mProgressBar.setProgress(0);
}
@Override
public void onSuccess(File file) {
mDownloadBtn.setText("下載完成");
mStatus.setText(String.format("下載完成:%s", file.getPath()));
}
@Override
public void onFail(File file, String failInfo) {
mDownloadBtn.setText("開始下載");
mDownloadBtn.setEnabled(true);
mStatus.setText(String.format("下載失?。?s", failInfo));
}
@Override
public void onProgress(int progress) {
mProgressBar.setProgress(progress);
}
});
}
});
}
}
DownloadHelper:
class DownloadHelper {
static void download(String url, String localPath, OnDownloadListener listener) {
DownloadAsyncTask task = new DownloadAsyncTask(url, localPath, listener);
task.execute();
}
private static class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
private String mFailInfo;
private String mUrl;
private String mFilePath;
private OnDownloadListener mListener;
DownloadAsyncTask(String mUrl, String mFilePath, OnDownloadListener mListener) {
this.mUrl = mUrl;
this.mFilePath = mFilePath;
this.mListener = mListener;
}
@Override
protected Boolean doInBackground(String... params) {
String pdfUrl = mUrl;
try {
URL url = new URL(pdfUrl);
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
int contentLength = urlConnection.getContentLength();
File pdfFile = new File(mFilePath);
if (pdfFile.exists()) {
boolean result = pdfFile.delete();
if (!result) {
mFailInfo = "存儲路徑下的同名文件刪除失??!";
return false;
}
}
int downloadSize = 0;
byte[] bytes = new byte[1024];
int length;
OutputStream out = new FileOutputStream(mFilePath);
while ((length = in.read(bytes)) != -1) {
out.write(bytes, 0, length);
downloadSize += length;
publishProgress(downloadSize / contentLength * 100);
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
mFailInfo = e.getMessage();
return false;
}
return true;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (mListener != null) {
mListener.onStart();
}
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (mListener != null) {
if (aBoolean) {
mListener.onSuccess(new File(mFilePath));
} else {
mListener.onFail(new File(mFilePath), mFailInfo);
}
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (values != null && values.length > 0) {
if (mListener != null) {
mListener.onProgress(values[0]);
}
}
}
}
interface OnDownloadListener{
void onStart();
void onSuccess(File file);
void onFail(File file, String failInfo);
void onProgress(int progress);
}
}
總結(jié)
以上所述是小編給大家介紹的Android中使用AsyncTask實(shí)現(xiàn)下載文件動態(tài)更新進(jìn)度條功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Kotlin注解實(shí)現(xiàn)Parcelable序列化流程詳解
有時我們會在界面跳轉(zhuǎn)的過程中,做對象傳值,這時就需要對該對象做序列化處理了。Android中對對象的序列化處理有兩種方式,這篇文章主要介紹了Kotlin注解實(shí)現(xiàn)Parcelable序列化2022-12-12
flutter 屏幕尺寸適配和字體大小適配的實(shí)現(xiàn)
這篇文章主要介紹了flutter 屏幕尺寸適配和字體大小適配的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
Android開發(fā)實(shí)現(xiàn)可拖動排序的ListView功能【附源碼下載】
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)可拖動排序的ListView功能,結(jié)合實(shí)例形式分析了Android列表拖動排序原理與相關(guān)操作技巧,并附帶完整源碼供讀者下載參考,需要的朋友可以參考下2017-11-11
在Android里完美實(shí)現(xiàn)基站和WIFI定位
眾所周知的,在OPhone和大部分國產(chǎn)的Android定制機(jī)里不支持最簡單實(shí)用的基站和WIFI定位,只能使用速度慢而耗電的GPS定位,但OPhone和華為/中興生產(chǎn)的一些Android定制機(jī)卻占據(jù)了一定的市場,因此導(dǎo)致了很多使用了定位技術(shù)的Andorid應(yīng)用挺尷尬的。2014-07-07
Android頁面之間進(jìn)行數(shù)據(jù)回傳的方法分析
這篇文章主要介紹了Android頁面之間進(jìn)行數(shù)據(jù)回傳的方法,結(jié)合實(shí)例形式分析了Android頁面之間進(jìn)行數(shù)據(jù)的傳遞與處理技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-06-06
Android自定義view實(shí)現(xiàn)滑動解鎖效果
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)滑動解鎖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05

