文/大大大大峰哥
序
AsyncTask是基于異步消息處理機制,只是Android為了方便我們使用,將它封裝了起來,這讓我們可以更加簡單便捷的使用,可以輕松地從子線程切換到主線程。如果想簡單了解異步消息處理機制可以看我另外一篇博文簡單描述Android異步原理。
使用
AsyncTask是一個抽象類,使用它需要繼承它,繼承的時候需要注意它擁有三個泛型參數:Params
,Progress
,Result
。
Params:需要傳入
的參數,用于后臺任務中使用,如果你不需要傳入數據可以將該設置為Void
。
Progress:后臺任務執行時,往往需要了解后臺任務的進度,這個參數自行設定成為你需要反映進度的數據類型,比如我需要將進度用Integer返回等等。
Result:當任務執行完畢后,則使用該類型作為反饋類型
,比如使用Boolean類型,那么你可以返回true告訴主線程,我成功運行。
方法
在我們繼承AsyncTask后,我們需要了解幾個重用的重寫方法。
onPreExecute():在我們使用AsyncTask需要初始化
操作的時候,我們可以重寫該方法并在里面初始數據以及UI。比如我們可以初始化一個下載進度條。
doInBackground(Params ...):這個是當你繼承AsyncTask必須
重寫的方法,該方法所有代碼均在子線程
中運行,一般是用來處理耗時
操作。比如我們在這方法向網絡獲取數據。
注意:因為在子線程中運行,那么就不能做更新UI的操作。
onProgressUpdate(Progress ...):在該類中調用publishProgress方法后,才會運行這個方法中的代碼,通過傳入的Progress類型后我們可以處理并更新UI。
onPostExecute(Result ):當我們后臺任務(doInBackground)執行完畢之后,return 傳遞的值進入onPostExecute方法中,向我們傳遞任務執行結果,比如我們可以關閉下載進度條對話框,并且提示下載成功或者失敗。
代碼
學習AsyncTask光靠理論說是不行的,所以需要看代碼來輔助理解,在看完之后自己敲一遍才是自己的東西,下面是做了一個模擬下載的功能。
(一)MainActivity.java
package com.example.deme2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton= (Button) findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new MyAsyncTask(MainActivity.this).execute();
}
});
}
}
(二)MyAsyncTask.java
package com.example.deme2;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import static android.content.ContentValues.TAG;
/**
* Created by TangZhiFeng on 2016/12/14.
*/
public class MyAsyncTask extends AsyncTask<Void, Integer
, Boolean> {
Context mContext;
AlertDialog mAlertDialog;
int mDownProgress;
public MyAsyncTask(Context context) {
mContext = context;
}
/*
* 這個函數一般是完成一些初始化操作。
* */
@Override
protected void onPreExecute() {
mDownProgress = 0;
mAlertDialog = new AlertDialog.Builder(mContext)
.setTitle("下載進度")
.setMessage(mDownProgress + "")
.create();
mAlertDialog.show();
}
/*
* 這個函數一般都是處理一些耗時操作,同時這個函數
* 是在子線程完成,不能進行UI更新操作
* */
@Override
protected Boolean doInBackground(Void... params) {
try {
while (true) {
mDownProgress = doDownload();//模擬下載過程
if (mDownProgress > 100) {
break;
}
Thread.sleep(1000);
publishProgress(mDownProgress);
Log.i(TAG, "doInBackground: "+mDownProgress);
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
private int doDownload() {
return mDownProgress+5;
}
/*
* 調用publishProgress后,進入這個函數,可以進
* 行UI操作
* */
@Override
protected void onProgressUpdate(Integer... values) {
mAlertDialog.setMessage("" + values[0]);
}
/*
* 在后臺任務執行完畢后調用該函數
* */
@Override
protected void onPostExecute(Boolean aBoolean) {
mAlertDialog.dismiss();//關閉對話框
if (aBoolean) {
Toast.makeText(mContext, "下載完成", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, "下載失敗", Toast.LENGTH_SHORT).show();
}
}
}
總結
End
希望大家多多指點,有問題指出來,互相幫助互相學習。