AsyncTask詳解及示例
- 總體概述
- 使用方法
- 一個簡單的例子
- 效果
- 專案結構
- activity_main.xml代碼
- MainActivity代碼
- SimpleAsyncTask代碼
- 進一步改進
總體概述
眾所周知,程式的執行主要是在UI執行緒上執行(也就是主執行緒),當有耗時任務的時候,例如從網路上下載檔案、進行資料庫查詢、進行復雜的邏輯運算的時候,如果在主執行緒中執行,會導致主執行緒阻塞,APP無法回應,asynctask是Android官方提供的幫助類,可以開啟個獨立執行緒執行某個耗時任務,
使用方法
AsyncTask是一個抽象類,如果使用必須用別的類來繼承他,主要的方法如下:
| 方法 | 作用 | 執行緒 |
|---|---|---|
| onPreExecute() | 程式執行前設定UI | 主執行緒 |
| doInBackground() | 在后臺執行的具體任務 | 子執行緒 |
| onProgressUpdate() | 程式執行程序中設定UI | 主執行緒 |
| onPostExecute() | 程式執行完設定UI | 主執行緒 |

AsyncTask <Params, Progress, Result>
| 引數名稱 | 引數作用 |
|---|---|
| Params | doInBackground()引數 |
| Progress | onProgressUpdated()引數 |
| Result | onPostExecute()引數 |
注意:
不需要寫引數就寫void
doInBackground必須實作,其他方法可以不實作
onPostExecute使用的引數是doInBackground的回傳值
doInBackground引數需要在構造AsyncTask時傳入
一個簡單的例子
點擊按鈕,文字變為Waiting,并且隨機等待一段時間后,更新文字內容,
(隨機等待一段時間模擬費時操作)
效果

專案結構

activity_main.xml代碼
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I am ready to start work!"
android:textSize="24sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:onClick="startTask"
android:text="Start Task"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1"/>
</androidx.constraintlayout.widget.ConstraintLayout>
代碼很好懂,Button系結個事件,在MainActivity中進行實作,
MainActivity代碼
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控制元件
mTextView = this.findViewById(R.id.textView1);
}
public void startTask(View view) {
mTextView.setText("Wait.......");
//開始AsyncTask
new SimpleAsyncTask(mTextView).execute();
}
}
其他代碼都很好懂,重點說一下這個:
new SimpleAsyncTask(mTextView).execute();
mTextView為什么傳入,其實就是SimpleAsyncTask這個的建構式所需要的引數,之后的execute就表示開始執行,因為onPreExecute不需要引數,所以這里不傳入,根據情況傳參,
SimpleAsyncTask代碼
public class SimpleAsyncTask extends AsyncTask<Void, Integer, String> {
private WeakReference<TextView> mTextView;
SimpleAsyncTask(TextView tv) {
//弱參考 可以被垃圾回識訓制回收如果必要的話
mTextView = new WeakReference<>(tv);
}
@Override
protected String doInBackground(Void... voids) {
Random r = new Random();
int n = r.nextInt(11);
int s = n * 200;
try {
Thread.sleep(s);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Awake at last after sleeping for " + s + " milliseconds!";
}
@Override
protected void onPostExecute(String s) {
// 引數String是doInBackground回傳的引數
// 因為是弱參考 必須用get方法獲得具體的物件
mTextView.get().setText(s);
}
}
首先講一下弱參考:
假如是普通的方法,當Activity被摧毀之后,對TextView的參考意味著Activity永遠不會被垃圾回識訓制回收,個人理解,因為你要用這個Activity,所以其不會被回收,會導致記憶體泄漏;弱參考,代表必要情況下可以被垃圾回識訓制回收,
doInBackground–必須實作的方法
該代碼中隨機暫停一段時間后,回傳字串,
onPostExecute–在doInBackground執行完后執行
String引數正是doInBackground的回傳值,并且這個是執行在UI執行緒上的,可以對UI進行更新,
進一步改進
在點擊按鈕之后,旋轉螢屏,會發現UI無法正常更新,這是因為旋轉螢屏重建了UI,但是AsyncTask會在后臺正常運行,但是無法更新UI,若想正常更新,需要AsyncTaskLoader,
可參考我的:(未來補上 哈哈哈哈)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/292755.html
標籤:其他
上一篇:AIDL入門學習一
