Java多執行緒之非同步任務——AsyncTask
阿新 • • 發佈:2019-01-03
為什麼需要非同步任務?
1、Android單執行緒模型
2、耗時操作放在非主執行緒中執行
AsyncTask為何而生?
1、子執行緒中更新UI
2、封裝、簡化非同步操作
構建AsyncTask子類的引數
AsyncTask<Params,Progress,Result>是一個抽象類,通常用於被繼承,繼承AsyncTask需要制定如下三個泛型引數:
Params:啟動任務是輸入引數的型別。
Progress:後臺任務執行中返回進度值的型別。
Result:後臺執行任務完成後返回結果的型別。
構建AsyncTask子類的回撥方法:
doInBackground:必須重寫,非同步執行後臺執行緒將要完成的任務;
onPreExecute: 執行後臺耗時操作前呼叫,通常使用者完成一些初始化操作;
onPostExecute:當doInBackground()完成後,系統會自動呼叫onPostExecute()方法,並將doInBackground()方法返回的值傳給該方法;
onProgressUpdate:在doInBackground()方法中呼叫publishProgress()方法更新任務的執行進度後,就會觸發該方法。
回撥方法的執行順序:
onPreExecute() -> doInBackground() -> onPostExecute()
在doInBackground()方法中呼叫publishProgress()方法更新任務的執行進度:
onPreExecute() -> doInBackground() -> onProgressUpdate() -> onPostExecute()
而後在MainActivity.java裡面new一個MyAsyncTask類,並呼叫execute()方法:
執行檢視Log列印情況:
別忘記新增網路訪問許可權,最後執行專案,結果如下圖:
非同步任務---AsyncTask使用的注意事項:
1、必須在UI執行緒中建立AsyncTask的例項
2、必須在UI執行緒中呼叫AsyncTask的execute()方法
3、重寫的四個方法是系統自動呼叫的,不應手動呼叫
4、每個AsyncTask只能被執行一次,多次呼叫將會引發異常(尤其注意)
1、Android單執行緒模型
2、耗時操作放在非主執行緒中執行
AsyncTask為何而生?
1、子執行緒中更新UI
2、封裝、簡化非同步操作
構建AsyncTask子類的引數
AsyncTask<Params,Progress,Result>是一個抽象類,通常用於被繼承,繼承AsyncTask需要制定如下三個泛型引數:
Params:啟動任務是輸入引數的型別。
Progress:後臺任務執行中返回進度值的型別。
Result:後臺執行任務完成後返回結果的型別。
構建AsyncTask子類的回撥方法:
doInBackground:必須重寫,非同步執行後臺執行緒將要完成的任務;
onPreExecute:
onPostExecute:當doInBackground()完成後,系統會自動呼叫onPostExecute()方法,並將doInBackground()方法返回的值傳給該方法;
onProgressUpdate:在doInBackground()方法中呼叫publishProgress()方法更新任務的執行進度後,就會觸發該方法。
回撥方法的執行順序:
onPreExecute() -> doInBackground() -> onPostExecute()
在doInBackground()方法中呼叫publishProgress()方法更新任務的執行進度:
onPreExecute() -> doInBackground() -> onProgressUpdate() -> onPostExecute()
完成初始化操作 完成耗時操作 更新進度條 得到doInBackground的返回值進行處理
接下來新建一個Android專案測試一下,新建Android專案之後,直接新增一個MyAsyncTask類:
public class MyAsyncTask extends AsyncTask<Void, Void, Void> { private static final String TAG = "MyAsyncTask"; @Override protected Void doInBackground(Void... arg0) { Log.e(TAG, "****doInBackground****"); publishProgress(); return null; } @Override protected void onPostExecute(Void result) { Log.e(TAG, "****onPostExecute****"); super.onPostExecute(result); } @Override protected void onPreExecute() { Log.e(TAG, "****onPreExecute****"); super.onPreExecute(); } @Override protected void onProgressUpdate(Void... values) { Log.e(TAG, "****onProgressUpdate****"); super.onProgressUpdate(values); } }
而後在MainActivity.java裡面new一個MyAsyncTask類,並呼叫execute()方法:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyAsyncTask task = new MyAsyncTask();
task.execute();
}
}
執行檢視Log列印情況:
根據列印的Log,我們可以發現四個方法的執行順序。
接下來我們修改一下並繼續編寫專案,簡單的使用一下AsyncTask。
MyAsyncTask類:
public class MyAsyncTask extends AsyncTask<String, Void, Bitmap> {
private static final String TAG = "MyAsyncTask";
private ImageView imageView;
public MyAsyncTask(ImageView imageView){
this.imageView = imageView;
}
@Override
protected Bitmap doInBackground(String... arg0) {
Log.e(TAG, "****doInBackground****");
publishProgress();
//獲取傳遞進來的引數
String url = arg0[0];
Bitmap bitmap = null;
URLConnection connection;
InputStream is;
try {
connection = new URL(url).openConnection();
is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
//通過decodeStream解析輸入流
bitmap = BitmapFactory.decodeStream(bis);
is.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
//將Bitmap作為返回值
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
Log.e(TAG, "****onPostExecute****");
imageView.setImageBitmap(bitmap);
super.onPostExecute(bitmap);
}
@Override
protected void onPreExecute() {
Log.e(TAG, "****onPreExecute****");
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Void... values) {
Log.e(TAG, "****onProgressUpdate****");
super.onProgressUpdate(values);
}
}
MainActivity類:
public class MainActivity extends ActionBarActivity {
private final String URL = "https://www.baidu.com/img/bd_logo1.png";
private ImageView imageView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView1 = (ImageView) findViewById(R.id.imageView1);
MyAsyncTask task = new MyAsyncTask(imageView1);
task.execute(URL);
}
}
activity_main.xml佈局檔案:
<RelativeLayout 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"
tools:context="com.itman.asynctaskdemo.MainActivity" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_launcher" />
</RelativeLayout>
別忘記新增網路訪問許可權,最後執行專案,結果如下圖:
非同步任務---AsyncTask使用的注意事項:
1、必須在UI執行緒中建立AsyncTask的例項
2、必須在UI執行緒中呼叫AsyncTask的execute()方法
3、重寫的四個方法是系統自動呼叫的,不應手動呼叫
4、每個AsyncTask只能被執行一次,多次呼叫將會引發異常(尤其注意)