詳解Android App中的AsyncTask異步任務(wù)執(zhí)行方式
基本概念
AsyncTask:異步任務(wù),從字面上來說,就是在我們的UI主線程運行的時候,異步的完成一些操作。AsyncTask允許我們的執(zhí)行一個異步的任務(wù)在后臺。我們可以將耗時的操作放在異步任務(wù)當中來執(zhí)行,并隨時將任務(wù)執(zhí)行的結(jié)果返回給我們的UI線程來更新我們的UI控件。通過AsyncTask我們可以輕松的解決多線程之間的通信問題。
怎么來理解AsyncTask呢?通俗一點來說,AsyncTask就相當于Android給我們提供了一個多線程編程的一個框架,其介于Thread和Handler之間,我們?nèi)绻x一個AsyncTask,就需要定義一個類來繼承AsyncTask這個抽象類,并實現(xiàn)其唯一的一個 doInBackgroud 抽象方法。要掌握AsyncTask,我們就必須要一個概念,總結(jié)起來就是: 3個泛型,4個步驟。
3個泛型指的是什么呢?我們來看看AsyncTask這個抽象類的定義,當我們定義一個類來繼承AsyncTask這個類的時候,我們需要為其指定3個泛型參數(shù):
AsyncTask <Params, Progress, Result>
- Params: 這個泛型指定的是我們傳遞給異步任務(wù)執(zhí)行時的參數(shù)的類型
- Progress: 這個泛型指定的是我們的異步任務(wù)在執(zhí)行的時候?qū)?zhí)行的進度返回給UI線程的參數(shù)的類型
- Result: 這個泛型指定的異步任務(wù)執(zhí)行完后返回給UI線程的結(jié)果的類型
我們在定義一個類繼承AsyncTask類的時候,必須要指定好這三個泛型的類型,如果都不指定的話,則都將其寫成Void,例如:
AsyncTask <Void, Void, Void>
4個步驟:當我們執(zhí)行一個異步任務(wù)的時候,其需要按照下面的4個步驟分別執(zhí)行
- onPreExecute(): 這個方法是在執(zhí)行異步任務(wù)之前的時候執(zhí)行,并且是在UI Thread當中執(zhí)行的,通常我們在這個方法里做一些UI控件的初始化的操作,例如彈出要給ProgressDialog
- doInBackground(Params... params): 在onPreExecute()方法執(zhí)行完之后,會馬上執(zhí)行這個方法,這個方法就是來處理異步任務(wù)的方法,Android操作系統(tǒng)會在后臺的線程池當中開啟一個worker thread來執(zhí)行我們的這個方法,所以這個方法是在worker thread當中執(zhí)行的,這個方法執(zhí)行完之后就可以將我們的執(zhí)行結(jié)果發(fā)送給我們的最后一個 onPostExecute 方法,在這個方法里,我們可以從網(wǎng)絡(luò)當中獲取數(shù)據(jù)等一些耗時的操作
- onProgressUpdate(Progess... values): 這個方法也是在UI Thread當中執(zhí)行的,我們在異步任務(wù)執(zhí)行的時候,有時候需要將執(zhí)行的進度返回給我們的UI界面,例如下載一張網(wǎng)絡(luò)圖片,我們需要時刻顯示其下載的進度,就可以使用這個方法來更新我們的進度。這個方法在調(diào)用之前,我們需要在 doInBackground 方法中調(diào)用一個 publishProgress(Progress) 的方法來將我們的進度時時刻刻傳遞給 onProgressUpdate 方法來更新
- onPostExecute(Result... result): 當我們的異步任務(wù)執(zhí)行完之后,就會將結(jié)果返回給這個方法,這個方法也是在UI Thread當中調(diào)用的,我們可以將返回的結(jié)果顯示在UI控件上
為什么我們的AsyncTask抽象類只有一個 doInBackground 的抽象方法呢??原因是,我們?nèi)绻鲆粋€異步任務(wù),我們必須要為其開辟一個新的Thread,讓其完成一些操作,而在完成這個異步任務(wù)時,我可能并不需要彈出要給ProgressDialog,我并不需要隨時更新我的ProgressDialog的進度條,我也并不需要將結(jié)果更新給我們的UI界面,所以除了doInBackground 方法之外的三個方法,都不是必須有的,因此我們必須要實現(xiàn)的方法是 doInBackground 方法。
實例
下面實現(xiàn)一個打開網(wǎng)絡(luò)圖片的demo:
package com.app.main; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Main extends Activity { String url = "http://e.hiphotos.baidu.com/image/w%3D2048/sign=61711bd121a446237ecaa262ac1a730e/e850352ac65c10385f10af69b3119313b07e892a.jpg"; ImageView imgView = null; Button btn = null; ProgressDialog dialog = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imgView = (ImageView) this.findViewById(R.id.imageview); btn = (Button) this.findViewById(R.id.btn); dialog = new ProgressDialog(this); dialog.setMessage("下載圖片中......"); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { new MyTask().execute(url); } }); } class MyTask extends AsyncTask<String, Void, Bitmap> { @Override protected void onPreExecute() { super.onPreExecute(); dialog.show(); } @Override protected Bitmap doInBackground(String... params) { Bitmap bitmap = null; String url = params[0]; HttpClient client = new DefaultHttpClient(); HttpGet getMethod = new HttpGet(url); try { HttpResponse response = client.execute(getMethod); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity entity = response.getEntity(); byte[] data = EntityUtils.toByteArray(entity); bitmap = BitmapFactory .decodeByteArray(data, 0, data.length); } } catch (Exception e) { } return bitmap; } @SuppressLint("NewApi") @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); imgView.setImageBitmap(result); dialog.dismiss(); } } }
實現(xiàn)的效果如圖:
相關(guān)文章
Android Lottie實現(xiàn)中秋月餅變明月動畫特效實例
Lottie是Airbnb開源的一個支持 Android、iOS 以及 ReactNative,利用json文件的方式快速實現(xiàn)動畫效果的庫,下面這篇文章主要給大家介紹了關(guān)于Android Lottie實現(xiàn)中秋月餅變明月動畫特效的相關(guān)資料,需要的朋友可以參考下2021-09-09淺談Android Studio如何Debug對應so文件C/C++代碼
本篇文章主要介紹了淺談Android Studio如何Debug對應so文件C/C++代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12Android BottomNavigationView底部導航效果
這篇文章主要為大家詳細介紹了Android BottomNavigationView底部導航效果的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01Android 中RxPermissions 的使用方法詳解
這篇文章主要介紹了Android 中RxPermissions 的使用方法詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-10-10