-
AsyncTask. 異步任務(wù)
目的:方便后臺(tái)線程中操作后
更新UI
封裝并簡(jiǎn)化了異步操作實(shí)現(xiàn):
Thread和Handler進(jìn)行了封裝實(shí)質(zhì):
Handler異步消息處理機(jī)制參數(shù)是泛型:
<Params,Progress,Result>UI操作:
onPreExecute,onPostExecute后臺(tái)線程操作
doInBackground輸入輸出:
Params(入),Result(出)進(jìn)度顯示:
onProgressUpdate
-
ANR(Application Not Responding)
- 應(yīng)用程序無(wú)響應(yīng),
原因:UI線程被耗時(shí)任務(wù)(網(wǎng)絡(luò)請(qǐng)求、下載上傳、加載圖片等)阻塞,界面卡死;
所以,
注意適當(dāng)開(kāi)啟異步任務(wù)、子線程;
處理耗時(shí)操作,防止UI線程出現(xiàn)ANR現(xiàn)象
- 應(yīng)用程序無(wú)響應(yīng),
UI線程做主線程,
子線程做工作線程;-
如果在子線程更新UI更新主線程的東西,
app會(huì)閃退,崩潰,
保證線程安全;
子線程可以通過(guò)以下幾個(gè)方法,
切換到主線程更新:Activity.runOnUiThread(Runnable)View.post(Runnable)View.postDelayed(Runnable,long)
AsyncTask解析
-
查看AsyncTask源碼:
可以在項(xiàng)目的任意位置,Ctrl+N,打開(kāi)輸入框,輸入想要查看的類名,
點(diǎn)擊搜索到的類名,即可前往查看源碼: -
可以看到首先AsyncTask它是個(gè)抽象類,
參數(shù)都是泛型:
使用
- 使用時(shí)首先需要新建一個(gè)類,
繼承自AsyncTask,
泛型要填包裝類,或者自定義的Model類型,
系統(tǒng)要求至少一定要繼承doInBackground()這個(gè)方法,
即在后臺(tái)子線程進(jìn)行的一個(gè)方法,
doInBackground()的參數(shù)類型,
即泛型的第一個(gè)參數(shù)類型,即入?yún)arams的參數(shù)類型,
return 返回的是結(jié)果,即泛型的第三個(gè)參數(shù):
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
@Override
protected Boolean doInBackground(String... strings) {
return null;
}
}
String...中的三個(gè)點(diǎn),
表示該參數(shù)的長(zhǎng)度是可變的;寫(xiě)完定義類之后,
在主線程new一下即可,
使用execute(),傳入可變長(zhǎng)度的入?yún)ⅲ?br> 即可啟動(dòng)AsyncTask:
public class MainActivity extends AppCompatActivity {
//logt 然后回車,快速生成?。。。。。。?!
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadAsyncTask().execute("哈嘍", "早上好");
}
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
/**
* 方法執(zhí)行在異步任務(wù)之前,執(zhí)行在主線程中?。? * 方法體中,可以 ;‘’;操作UI !!
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... params) {
// fori 回車 快速生成?。。。。。。。。。。? for (int i = 0; i < 10000; i++) {
Log.i(TAG, "doInBackground " + i +
": " + params[0] + "," + params[1]);
}
return true;
}
}
}
運(yùn)行:
-
各方法作用概述,如代碼中注釋:
public class MainActivity extends AppCompatActivity {
//logt 然后回車,快速生成?。。。。。。?!
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadAsyncTask().execute("哈嘍", "早上好");
}
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
/**
* 方法執(zhí)行在異步任務(wù)之前,執(zhí)行在主線程中??!
* 方法體中,可以 ;‘’;操作UI ??!
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* 本方法運(yùn)行在子線程中,
* 處理工作內(nèi)容、耗時(shí)操作
*
* @param params
* @return
*/
@Override
protected Boolean doInBackground(String... params) {
// fori 回車 快速生成?。。。。。。。。。?!
for (int i = 0; i < 10000; i++) {
Log.i(TAG, "doInBackground " + i +
": " + params[0] + "," + params[1]);
publishProgress(i);//拋出進(jìn)度
}
return true;
}
/**
* 本方法運(yùn)行在主線程中,可以處理結(jié)果
* 當(dāng)任務(wù)執(zhí)行完了,即doInBackground()一旦return,
* 其return的值就會(huì)傳到這里,作為參數(shù),
* 參數(shù)類型即定義泛型時(shí)的第三個(gè)參數(shù)
* @param aBoolean
*/
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
}
/**
* 本方法運(yùn)行在主線程
* 進(jìn)度變化就在這個(gè)方法處理
* 接收來(lái)自 doInBackground()中 publishProgress()拋出的進(jìn)度,
* 并處理
*
* @param values 類型是定義時(shí)的第二個(gè)泛型參數(shù),
* 數(shù)據(jù)來(lái)自 doInBackground()的 publishProgress()
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
}
}
補(bǔ)充
-
onCancelled():- 運(yùn)行在:主線程
調(diào)用時(shí)刻:當(dāng)異步任務(wù)被取消時(shí)被調(diào)用
作用:可用于做界面取消的更新
- 運(yùn)行在:主線程
注意:
不要直接調(diào)用onPreExecute()、doInBackground()、onProgressUpdate()、onPostExecute()和onCancelled()方法
AsyncTask對(duì)象必須在主線程創(chuàng)建;開(kāi)始和結(jié)束異步任務(wù)的方法:
execute(Params...params)
必須在主線程中調(diào)用,參數(shù)為泛型定義的第一參,即入?yún)?/code>!
作用:表示開(kāi)始一個(gè)異步任務(wù)
注意:一個(gè)異步對(duì)象只能調(diào)用一次execute()方法cancel(booleanmayInterruptIfRunning)
必須在主線程中調(diào)用
作用:表示停止一個(gè)異步任務(wù)

