Android线程机制——AsyncTask
對于Android為什么要使用多線程,因為從Android4.0之后,谷歌規(guī)定了網(wǎng)絡(luò)操作不允許放在主線程中執(zhí)行,由此就有了多線程的機(jī)制,有個JAVA學(xué)習(xí)經(jīng)驗的朋友一定知道多線程指的是什么,簡單來講就是,在JAVA程序中,main()函數(shù)開啟的即為這個程序的主線程,而我們?yōu)榱送瓿梢恍┖臅r操作又不想影響到主線程的執(zhí)行,這是我們往往通過Thread對象創(chuàng)建一個子線程來執(zhí)行。簡單的說,一個程序只有一個主線程,可以有多個主線程。在Android世界中也是這樣,Android屬于單線程模型,耗時操作必須放在非主線程中執(zhí)行,故而谷歌為了方便我們使用線程,為我們提供一個AsyncTask多線程操作對象。
對于Android使用線程還有一點需要特別注意,哪就是Android不允許在子線程中更新UI,相信很多初學(xué)者一定遇到過這個問題,這個怎么解決呢?在Activity中,我們可以通過
new Thread(new Runnable() {@Overridepublic void run() {Log.v("abc", "子線程執(zhí)行");runOnUiThread(new Runnable() {@Overridepublic void run() {Log.v("abc", "返回主線程執(zhí)行");}});}}).start();來實現(xiàn)我們的效果,不過有一點需要注意的是,在Fragement中,runOnUiThread()不能使用,所以大家在使用時稍微注意一下即可。當(dāng)然了Android中我們還可以通過Handler+Messager來完成多線程操作,對于這里個的使用,在之前的博客中已經(jīng)為大家介紹,就不在贅述,下面我們開始介紹本篇的重點:AsyncTask的使用。
AsyncTask<Parans, Progress, Result>是一個抽象類,我們需要首先實現(xiàn)這個抽象類,然后才能使用,對于它的三個參數(shù):Parans:啟動任務(wù)時輸入的參數(shù)類型;progress:后臺任務(wù)執(zhí)行中返回值的類型;Result:后臺執(zhí)行任務(wù)完成后返回的結(jié)果類型。
構(gòu)建AsyncTask子類的回調(diào)方法:1、doInBackground:必須重寫,異步執(zhí)行后臺線程將要完成的任務(wù); 2、onPreExecute:執(zhí)行后臺耗時操作前被調(diào)用,通過用戶完成一些初始化操作;3、onPostExecute:當(dāng)doInBackground()完成之后,系統(tǒng)會自動調(diào)用,并將doInBackground()執(zhí)行后的返回值,傳遞給onPostExecute()方法,簡單來說就是,doInBackground()完成耗時操作,結(jié)果交個onPostExecute()方法更新UI;4、onProgressUpdate:在doInBackground()方法中,調(diào)用publishProgress()方法,更新任務(wù)的執(zhí)行進(jìn)度后,就會觸發(fā)該方法。
說了這么多,相信你心中還有一定的疑惑,下面我們通過兩個簡單的Android小程序,為大家具體介紹一下AsyncTask的使用方法:
a、AsyncTask中是個抽象方法的執(zhí)行順序:
1、創(chuàng)建一個AsyncTask子類對象:
public class MyAsyncTask extends AsyncTask<Void, Void, Void> {@Overrideprotected void onPreExecute() {super.onPreExecute();Log.v("abc", "onPreExecute");}@Overrideprotected Void doInBackground(Void... arg0) {Log.v("abc", "doInBackground");publishProgress(arg0);return null;}@Overrideprotected void onPostExecute(Void result) {super.onPostExecute(result);Log.v("abc", "onPostExecute");}@Overrideprotected void onProgressUpdate(Void... values) {super.onProgressUpdate(values);Log.v("abc", "onProgressUpdate");}}2、在MainActivity中調(diào)用給子線程,進(jìn)行執(zhí)行:
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);new MyAsyncTask().execute();//啟動執(zhí)行 }3、執(zhí)行后打印的log日志:
通過這個日志信息,是不是解決了你心中的疑惑,下面我們看一個使用AsyncTask加載網(wǎng)絡(luò)圖片的例子。
b、加載網(wǎng)絡(luò)圖片:
1、首先創(chuàng)建一個承載Activity布局文件的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"android:layout_margin="10dp"tools:context=".MainActivity" ><ImageView android:id="@+id/img"android:layout_width="match_parent"android:layout_height="match_parent"/><ProgressBar android:id="@+id/progressbar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:visibility="gone"android:layout_centerInParent="true"/></RelativeLayout>布局文件很簡單,就是一個ImageView+ProgressBar,在加載ImageView是我們通過ProgressBar來提醒用戶等待。
2、創(chuàng)建我們的Activity對象:
public class AsyncTaskImager extends Activity {private ProgressBar pb;private ImageView image;private static final String url = "https://www.baidu.com/img/bdlogo.png";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.imager);init();new ImageAsyncTask().execute(url);}private void init() {pb = (ProgressBar) findViewById(R.id.progressbar);image = (ImageView) findViewById(R.id.img);}class ImageAsyncTask extends AsyncTask<String, Void, Bitmap>{@Overrideprotected void onPreExecute() {super.onPreExecute();pb.setVisibility(View.VISIBLE);}@Overrideprotected Bitmap doInBackground(String... params) {Bitmap bitmap = null;URLConnection conn = null;String url = params[0];try {conn = new URL(url).openConnection();InputStream in = conn.getInputStream();BufferedInputStream bis = new BufferedInputStream(in);bitmap = BitmapFactory.decodeStream(bis);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return bitmap;}@Overrideprotected void onPostExecute(Bitmap result) {super.onPostExecute(result);pb.setVisibility(View.GONE);image.setImageBitmap(result);}}}到這里我們的大功已經(jīng)基本完成了,最后不要忘記在AndroidManifest.xml中進(jìn)行一下聲明。
3、添加網(wǎng)絡(luò)操作權(quán)限:
<uses-permission android:name="android.permission.INTERNET"/>因為我們需要使用到網(wǎng)絡(luò)連接,所以我們需要在AndroidManifest.xml中添加一個網(wǎng)絡(luò)訪問權(quán)限。
4、最后配上一張運行結(jié)果:
到這里關(guān)于AsyncTask的介紹就可以畫上一個句號了,大家有什么疑問,歡迎留言討論。對于本人理解上的不足,歡迎批評指點。謝謝
總結(jié)
以上是生活随笔為你收集整理的Android线程机制——AsyncTask的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php5.5.* mysqlnd驱动安装
- 下一篇: 如何用rake tasks 生成migr