當前位置:
首頁 > 知識 > AsyncTask用法解析-下載文件動態更新進度條

AsyncTask用法解析-下載文件動態更新進度條

1. 泛型

AysncTask<Params, Progress, Result>

Params:啟動任務時傳入的參數,通過調用asyncTask.execute(param)方法傳入。

Progress:後台任務執行的進度,若不用顯示進度條,則不需要指定。

Result:後台任務結束時返回的結果。

2. 重要方法

doInBackground(Params... params):必須重寫的方法,後台任務就在這裡執行,會開啟一個新的線程。params為啟動任務時傳入的參數,參數個數不定。

onPreExecute:在主線程中調用,在後台任務開啟前的操作在這裡進行,例如顯示一個進度條對話框。

onPostExecute(Result result):當後台任務結束後,在主線程中調用,處理doInBackground方法返回的結果。

onProgressUpdate(Progress... values):當在doInBackground中調用publishProgress(Progress... values)時,返回主線程中調用,這裡的參數個數也是不定的。

onCancelled:取消任務。

AsyncTask用法解析-下載文件動態更新進度條

3. 注意事項

(1)execute方法必須在主線程中調用;

(2)AsyncTask實例必須在主線程中創建;

(3)不要手動調用doInBackground、onPreExecute、onPostExecute、onProgressUpdate方法;

(4)注意防止內存泄漏,在doInBackground方法中若出現對Activity的強引用,可能會造成內存泄漏。

4. 下載文件動態更新進度條(未封裝)

布局:

<?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"
stylex="?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實例必須在主線程創建
DownloadAsyncTask asyncTask = new DownloadAsyncTask;
asyncTask.execute(PDF_URL);
}
});
}

/**
* 泛型:
* String:傳入參數為文件下載地址
* Integer:下載過程中更新ProgressBar的進度
* 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;//獲取內容總長度

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;//已經下載的大小
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. 下載文件動態更新進度條(封裝)

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);
}
}

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

salesforce零基礎學習(七十八)線性錶鏈形結構簡單實現
「EASYDOM系列教程」索引
Tp3.2提交表單與操作表單
Handler案例-簡易打地鼠遊戲

TAG:達人科技 |

您可能感興趣

Python 調用 Micro 宏自動解析 Nmon 文件進行數據歸檔
剖析關於-ansible配置文件和命令中ad-hoc模式使用參數詳解
MyBatis配置文件詳解
更改iPhone上通過Safari瀏覽器下載文件位置的方法!
Mybatis配置文件
Web Pages 文件
CodeWarrior IDE使用Tips-使用burner將elf文件轉換生成HEX和BIN文件的方法和步驟詳解
通過iqy文件傳播FlawedAmmyy惡意軟體
讀取ClassPath下resource文件的正確姿勢
Ubuntu 下面 MySQL 的參數文件 my.cnf 淺析
Avante Technology發布Emendo Cloud 3D列印文件自動分析和維修服務
QuickLook 應用——讓 Windows 10 像 macOS 一樣快速預覽文件
Microsoft拖放文件支持更新Office,OneDrive iOS應用程序
WordPress插件WooCommerce任意文件刪除漏洞分析
vue-cli 腳手架中 webpack 配置基礎文件詳解
Python使用pandas讀取Excel文件多個WorkSheet的數據並繪製柱狀圖和熱力圖
redis.conf配置文件詳解
滲透技巧——Windows下NTFS文件的USN Journal
Microsoft Teams 升級機制允許黑客執行任意文件
通過調用Windows命令,將chm 文件轉換為html 文件