-
AsyncTask. 異步任務
- **目的:友善背景線程中操作後
更新UI
- **目的:友善背景線程中操作後
封裝并簡化了
異步操作
**
- 實作:`Thread`和`Handler`進行了封裝
- 實質:`Handler`異步消息處理機制
- 參數是泛型:`<Params,Progress,Result>`
- UI操作:`onPreExecute`,`onPostExecute`
- 背景線程操作 `doInBackground`
- 輸入輸出:`Params`(入),`Result`(出)
- 進度顯示:`onProgressUpdate`
-
ANR(Application Not Responding)
- 應用程式無響應,
**原因:UI線程被耗時任務(網絡請求、下載下傳上傳、加載圖檔等)阻塞,界面卡死;
是以,
注意适當開啟異步任務、子線程;
處理耗時操作,防止UI線程出現ANR現象**
- UI線程做主線程,
子線程做工作線程;
- 如果在子線程更新UI更新主線程的東西,
app會閃退,崩潰,
保證線程安全;
子線程可以通過以下幾個方法,
切換到主線程更新:
- `Activity.runOnUiThread(Runnable)`
- `View.post(Runnable)`
- `View.postDelayed(Runnable,long)`
AsyncTask解析
-
**檢視AsyncTask源碼:
可以在項目的任意位置,Ctrl+N,打開輸入框,輸入想要檢視的類名,
點選搜尋到的類名,即可前往檢視源碼:**
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iNhVjZidTY2QjZ5E2YkFmYzIjM0cDN2UTZmZDMwczM58CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
- **可以看到首先AsyncTask它是個抽象類,
參數都是泛型:
使用
- **使用時首先需要建立一個類,
自繼承
,AsyncTask
泛型
要填
包裝類
,或者自定義的
Model類型
系統要求至少一定要繼承
doInBackground()
這個方法,
即在
背景子線程
進行的一個方法,
doInBackground()
的
參數類型
即泛型的
第一個參數類型
,即
入參Params
參數類型
return 傳回的是結果,即泛型的第三個參數:**
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
@Override
protected Boolean doInBackground(String... strings) {
return null;
}
}
-
中的三個點,String...
表示該參數的長度是可變的;**
- **寫完定義類之後,
在主線程
new
一下即可,
execute()
,傳入可變長度的入參,
即可啟動
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> {
/**
* 方法執行在異步任務之前,執行在主線程中!!
* 方法體中,可以 ;‘’;操作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;
}
}
}
運作:
-
各方法作用概述,如代碼中注釋:
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> {
/**
* 方法執行在異步任務之前,執行在主線程中!!
* 方法體中,可以 ;‘’;操作UI !!
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* 本方法運作在子線程中,
* 處理工作内容、耗時操作
*
* @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);//抛出進度
}
return true;
}
/**
* 本方法運作在主線程中,可以處理結果
* 當任務執行完了,即doInBackground()一旦return,
* 其return的值就會傳到這裡,作為參數,
* 參數類型即定義泛型時的第三個參數
* @param aBoolean
*/
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
}
/**
* 本方法運作在主線程
* 進度變化就在這個方法處理
* 接收來自 doInBackground()中 publishProgress()抛出的進度,
* 并處理
*
* @param values 類型是定義時的第二個泛型參數,
* 資料來自 doInBackground()的 publishProgress()
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
}
}
補充
-
:onCancelled()
- 運作在:主線程
調用時刻:當異步任務被取消時被調用
作用:可用于做界面取消的更新
- 注意:
不要直接調用
onPreExecute()
、
doInBackground()
onProgressUpdate()
onPostExecute()
和
onCancelled()
方法
AsyncTask對象必須在主線程建立;
- 開始和結束異步任務的方法:
execute(Params...params)
必須在
主線程
中調用,
參數
為泛型定義的
第一參
入參
!
作用:表示開始一個異步任務
注意:一個異步對象隻能調用一次execute()方法
-
cancel(booleanmayInterruptIfRunning)
主線程
中調用
作用:表示停止一個異步任務