詳解Android App中的AsyncTask異步任務(wù)執(zhí)行方式
基本概念
AsyncTask:異步任務(wù),從字面上來(lái)說(shuō),就是在我們的UI主線程運(yùn)行的時(shí)候,異步的完成一些操作。AsyncTask允許我們的執(zhí)行一個(gè)異步的任務(wù)在后臺(tái)。我們可以將耗時(shí)的操作放在異步任務(wù)當(dāng)中來(lái)執(zhí)行,并隨時(shí)將任務(wù)執(zhí)行的結(jié)果返回給我們的UI線程來(lái)更新我們的UI控件。通過(guò)AsyncTask我們可以輕松的解決多線程之間的通信問(wèn)題。
怎么來(lái)理解AsyncTask呢?通俗一點(diǎn)來(lái)說(shuō),AsyncTask就相當(dāng)于Android給我們提供了一個(gè)多線程編程的一個(gè)框架,其介于Thread和Handler之間,我們?nèi)绻x一個(gè)AsyncTask,就需要定義一個(gè)類(lèi)來(lái)繼承AsyncTask這個(gè)抽象類(lèi),并實(shí)現(xiàn)其唯一的一個(gè) doInBackgroud 抽象方法。要掌握AsyncTask,我們就必須要一個(gè)概念,總結(jié)起來(lái)就是: 3個(gè)泛型,4個(gè)步驟。
3個(gè)泛型指的是什么呢?我們來(lái)看看AsyncTask這個(gè)抽象類(lèi)的定義,當(dāng)我們定義一個(gè)類(lèi)來(lái)繼承AsyncTask這個(gè)類(lèi)的時(shí)候,我們需要為其指定3個(gè)泛型參數(shù):
AsyncTask <Params, Progress, Result>
- Params: 這個(gè)泛型指定的是我們傳遞給異步任務(wù)執(zhí)行時(shí)的參數(shù)的類(lèi)型
- Progress: 這個(gè)泛型指定的是我們的異步任務(wù)在執(zhí)行的時(shí)候?qū)?zhí)行的進(jìn)度返回給UI線程的參數(shù)的類(lèi)型
- Result: 這個(gè)泛型指定的異步任務(wù)執(zhí)行完后返回給UI線程的結(jié)果的類(lèi)型
我們?cè)诙x一個(gè)類(lèi)繼承AsyncTask類(lèi)的時(shí)候,必須要指定好這三個(gè)泛型的類(lèi)型,如果都不指定的話,則都將其寫(xiě)成Void,例如:
AsyncTask <Void, Void, Void>
4個(gè)步驟:當(dāng)我們執(zhí)行一個(gè)異步任務(wù)的時(shí)候,其需要按照下面的4個(gè)步驟分別執(zhí)行
- onPreExecute(): 這個(gè)方法是在執(zhí)行異步任務(wù)之前的時(shí)候執(zhí)行,并且是在UI Thread當(dāng)中執(zhí)行的,通常我們?cè)谶@個(gè)方法里做一些UI控件的初始化的操作,例如彈出要給ProgressDialog
- doInBackground(Params... params): 在onPreExecute()方法執(zhí)行完之后,會(huì)馬上執(zhí)行這個(gè)方法,這個(gè)方法就是來(lái)處理異步任務(wù)的方法,Android操作系統(tǒng)會(huì)在后臺(tái)的線程池當(dāng)中開(kāi)啟一個(gè)worker thread來(lái)執(zhí)行我們的這個(gè)方法,所以這個(gè)方法是在worker thread當(dāng)中執(zhí)行的,這個(gè)方法執(zhí)行完之后就可以將我們的執(zhí)行結(jié)果發(fā)送給我們的最后一個(gè) onPostExecute 方法,在這個(gè)方法里,我們可以從網(wǎng)絡(luò)當(dāng)中獲取數(shù)據(jù)等一些耗時(shí)的操作
- onProgressUpdate(Progess... values): 這個(gè)方法也是在UI Thread當(dāng)中執(zhí)行的,我們?cè)诋惒饺蝿?wù)執(zhí)行的時(shí)候,有時(shí)候需要將執(zhí)行的進(jìn)度返回給我們的UI界面,例如下載一張網(wǎng)絡(luò)圖片,我們需要時(shí)刻顯示其下載的進(jìn)度,就可以使用這個(gè)方法來(lái)更新我們的進(jìn)度。這個(gè)方法在調(diào)用之前,我們需要在 doInBackground 方法中調(diào)用一個(gè) publishProgress(Progress) 的方法來(lái)將我們的進(jìn)度時(shí)時(shí)刻刻傳遞給 onProgressUpdate 方法來(lái)更新
- onPostExecute(Result... result): 當(dāng)我們的異步任務(wù)執(zhí)行完之后,就會(huì)將結(jié)果返回給這個(gè)方法,這個(gè)方法也是在UI Thread當(dāng)中調(diào)用的,我們可以將返回的結(jié)果顯示在UI控件上
為什么我們的AsyncTask抽象類(lèi)只有一個(gè) doInBackground 的抽象方法呢??原因是,我們?nèi)绻鲆粋€(gè)異步任務(wù),我們必須要為其開(kāi)辟一個(gè)新的Thread,讓其完成一些操作,而在完成這個(gè)異步任務(wù)時(shí),我可能并不需要彈出要給ProgressDialog,我并不需要隨時(shí)更新我的ProgressDialog的進(jìn)度條,我也并不需要將結(jié)果更新給我們的UI界面,所以除了doInBackground 方法之外的三個(gè)方法,都不是必須有的,因此我們必須要實(shí)現(xiàn)的方法是 doInBackground 方法。
實(shí)例
下面實(shí)現(xiàn)一個(gè)打開(kāi)網(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(); } } }
實(shí)現(xiàn)的效果如圖:
- Android開(kāi)發(fā)筆記之:深入理解多線程AsyncTask
- Android的異步任務(wù)AsyncTask詳解
- Android中AsyncTask的用法實(shí)例分享
- Android AsyncTask完全解析 帶你從源碼的角度徹底理解
- 詳解Android中AsyncTask機(jī)制
- Android中通過(guò)AsyncTask類(lèi)來(lái)制作炫酷進(jìn)度條的實(shí)例教程
- Android中使用AsyncTask實(shí)現(xiàn)文件下載以及進(jìn)度更新提示
- Android AsyncTask實(shí)現(xiàn)異步處理任務(wù)的方法詳解
相關(guān)文章
詳解Android中Activity的啟動(dòng)模式及應(yīng)用場(chǎng)景
今天給大家介紹下安卓開(kāi)發(fā)中不得不涉及的Activity啟動(dòng)模式及應(yīng)用場(chǎng)景,Activity一共有四種啟動(dòng)模式,分別是Standard模式、SingleTop模式、SingleTask模式以及SingleInstance模式,,需要的朋友可以參考下2023-09-09Android Dialog中軟鍵盤(pán)的顯示與隱藏的示例
本篇文章主要介紹Android Dialog中軟鍵盤(pán)的顯示與隱藏的示例,這里整理了詳細(xì)的代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02Android Lottie實(shí)現(xiàn)中秋月餅變明月動(dòng)畫(huà)特效實(shí)例
Lottie是Airbnb開(kāi)源的一個(gè)支持 Android、iOS 以及 ReactNative,利用json文件的方式快速實(shí)現(xiàn)動(dòng)畫(huà)效果的庫(kù),下面這篇文章主要給大家介紹了關(guān)于Android Lottie實(shí)現(xiàn)中秋月餅變明月動(dòng)畫(huà)特效的相關(guān)資料,需要的朋友可以參考下2021-09-09Android提高之多級(jí)樹(shù)形菜單的實(shí)現(xiàn)方法
這篇文章主要介紹了Android多級(jí)樹(shù)形菜單的實(shí)現(xiàn)方法,很實(shí)用的功能,需要的朋友可以參考下2014-08-08淺談Android Studio如何Debug對(duì)應(yīng)so文件C/C++代碼
本篇文章主要介紹了淺談Android Studio如何Debug對(duì)應(yīng)so文件C/C++代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Android BottomNavigationView底部導(dǎo)航效果
這篇文章主要為大家詳細(xì)介紹了Android BottomNavigationView底部導(dǎo)航效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01Android 中RxPermissions 的使用方法詳解
這篇文章主要介紹了Android 中RxPermissions 的使用方法詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-10-10