Android笔记(三十六) AsyncTask是如何执行的?
? ? ??在上一個(gè)例子中,我們是在LoadImage的onPostExecute中修改的UI,不是說只允許在主線程中修改UI嗎?我們看一下源代碼是如何操作的。
? ? ? MainActicity.java
package cn.lixyz.asynctest;import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar;import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection;public class MainActivity extends Activity{private Button button;private ImageView imageView;private ProgressBar progressBar;private String URL="http://ww3.sinaimg.cn/bmiddle/612c96afjw1ewwftl3uqkj20u00koq48.jpg";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//獲取組件button = (Button) findViewById(R.id.button);imageView = (ImageView) findViewById(R.id.imageView);progressBar = (ProgressBar) findViewById(R.id.progressBar);//給button設(shè)置點(diǎn)擊事件,點(diǎn)擊按鈕,啟動(dòng)異步任務(wù)button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {new LoadImage().execute(URL);}});}class LoadImage extends AsyncTask<String,Void,Bitmap>{//開始執(zhí)行耗時(shí)操作,連接網(wǎng)絡(luò)獲取圖片,并且將Bitmap返回 @Overrideprotected Bitmap doInBackground(String... params) {String url = params[0];Bitmap bitmap = null;URLConnection connection;InputStream is;try {connection = new URL(url).openConnection();Thread.sleep(5000);is = connection.getInputStream();BufferedInputStream bis = new BufferedInputStream(is);bitmap = BitmapFactory.decodeStream(bis);is.close();bis.close();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}return bitmap;}//onPreExcute方法是在doInBackGround方法前執(zhí)行,用于做一些初始化操作,這里將progressBar顯示出來 @Overrideprotected void onPreExecute() {super.onPreExecute();progressBar.setVisibility(View.VISIBLE);}//doInBackGround方法執(zhí)行后,會(huì)自動(dòng)執(zhí)行該方法,獲取到doInBackGround返回的對(duì)象,然后更改UI @Overrideprotected void onPostExecute(Bitmap bitmap) {super.onPostExecute(bitmap);progressBar.setVisibility(View.GONE);imageView.setImageBitmap(bitmap);}} } View Code? ? ? acticity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="4"><ImageViewandroid:id="@+id/imageView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"/><ProgressBarandroid:id="@+id/progressBar"android:visibility="gone"android:layout_centerInParent="true"style="@style/Widget.AppCompat.ProgressBar"android:layout_width="wrap_content"android:layout_height="wrap_content" /></RelativeLayout><Buttonandroid:id="@+id/button"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center"android:text="點(diǎn)擊載入" /> </LinearLayout> View Code? ? ? 先找到AsyncTask的構(gòu)造函數(shù):
public AsyncTask() {mWorker = new WorkerRunnable<Params, Result>() {public Result call() throws Exception {mTaskInvoked.set(true);Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//noinspection uncheckedResult result = doInBackground(mParams);Binder.flushPendingCommands();return postResult(result);}};mFuture = new FutureTask<Result>(mWorker) {@Overrideprotected void done() {try {postResultIfNotInvoked(get());} catch (InterruptedException e) {android.util.Log.w(LOG_TAG, e);} catch (ExecutionException e) {throw new RuntimeException("An error occurred while executing doInBackground()",e.getCause());} catch (CancellationException e) {postResultIfNotInvoked(null);}}};}? ? ? 可以看到在AsyncTask的構(gòu)造函數(shù)中,僅僅初始化了兩個(gè)變量?mWorker?和?mFuture?
? ? ? 接著啟動(dòng)AsyncTask,我們找到?execute?方法:
@MainThreadpublic final AsyncTask<Params, Progress, Result> execute(Params... params) {return executeOnExecutor(sDefaultExecutor, params);}? ? ? 可以看到,在?execute()?方法中,只執(zhí)行了一個(gè)?executeOnExecutor()?,我們繼續(xù)看executeOnExecutor方法:
@MainThreadpublic final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params... params) {if (mStatus != Status.PENDING) {switch (mStatus) {case RUNNING:throw new IllegalStateException("Cannot execute task:"+ " the task is already running.");case FINISHED:throw new IllegalStateException("Cannot execute task:"+ " the task has already been executed "+ "(a task can be executed only once)");}}mStatus = Status.RUNNING;onPreExecute();mWorker.mParams = params;exec.execute(mFuture);return this;}? ? ? 可以看到,在?executeOnExecutor()?方法中,先判斷了AsyncTask的狀態(tài),如果是?RUNNING?或者是?FINISHED?的話,則會(huì)拋出?IllegalStateException?異常,如果不是,則將AsyncTask的狀態(tài)設(shè)置為?RUNNING ?,然后執(zhí)行?onPreExecute()?方法,我們?cè)倏催@個(gè)方法:
@MainThreadprotected void onPreExecute() {}? ? ? 這個(gè)方法又沒有做任何操作,之前我們講過,?onPreExecute()?方法是在執(zhí)行?doInBackGround()?之前執(zhí)行,用來做一些初始化操作的,所以如果我們有需要的話,就需要自己重寫?onPreExecute()?方法了。
接著看?executeOnExecutor()?方法,在執(zhí)行完?onPreExecute()?方法之后,繼續(xù)往下,將?params?賦值給?mWorker.mParams?之后,又執(zhí)行了?exec.execute(mFuture)?,?mFuture?是在前面的構(gòu)造方法中初始化的,我們看代碼:
public AsyncTask() {mWorker = new WorkerRunnable<Params, Result>() {public Result call() throws Exception {mTaskInvoked.set(true);Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//noinspection uncheckedResult result = doInBackground(mParams);Binder.flushPendingCommands();return postResult(result);}};mFuture = new FutureTask<Result>(mWorker) {@Overrideprotected void done() {try {postResultIfNotInvoked(get());} catch (InterruptedException e) {android.util.Log.w(LOG_TAG, e);} catch (ExecutionException e) {throw new RuntimeException("An error occurred while executing doInBackground()",e.getCause());} catch (CancellationException e) {postResultIfNotInvoked(null);}}};}可以看到在這里調(diào)用了?doInBackground()?方法,并最后返回了?postResult(result)?,再繼續(xù)看,找到?postResult(result)?
private Result postResult(Result result) {@SuppressWarnings("unchecked")Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,new AsyncTaskResult<Result>(this, result));message.sendToTarget();return result;}可以看到,在這部分代碼中,顯示獲取到了一個(gè)Handler,然后調(diào)用這個(gè)Handler對(duì)象的obtainMessage()方法得到一個(gè)Message對(duì)象,我們看一下獲取到的這個(gè)Handler對(duì)象:
private static Handler getHandler() {synchronized (AsyncTask.class) {if (sHandler == null) {sHandler = new InternalHandler();}return sHandler;}}發(fā)現(xiàn)是一個(gè)?InternalHandler?對(duì)象,繼續(xù)找這個(gè)?InternalHandler?對(duì)象
private static class InternalHandler extends Handler {public InternalHandler() {super(Looper.getMainLooper());}@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})@Overridepublic void handleMessage(Message msg) {AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;switch (msg.what) {case MESSAGE_POST_RESULT:// There is only one resultresult.mTask.finish(result.mData[0]);break;case MESSAGE_POST_PROGRESS:result.mTask.onProgressUpdate(result.mData);break;}}}這里就清楚了,獲取到的是一個(gè)?MainLooper?,也就是說獲取的是在主線程中的Handler,也就是說,上面的操作最后將Message發(fā)送到了主線程中,然后根據(jù)發(fā)送過來的消息是??MESSAGE_POST_RESULT ?還是?MESSAGE_POST_PROGRESS?來判斷該執(zhí)行什么方法
如果是?MESSAGE_POST_RESULT ?,我們查看finish方法:
private void finish(Result result) {if (isCancelled()) {onCancelled(result);} else {onPostExecute(result);}mStatus = Status.FINISHED;}到這里,就一目了然了,調(diào)用了onPostResult方法更新UI。
整個(gè)流程走完,會(huì)發(fā)現(xiàn)其實(shí)AsyncTask還是Handler機(jī)制,只不過是對(duì)線程做了優(yōu)化和封裝而已
?
更多內(nèi)容:
Android應(yīng)用AsyncTask處理機(jī)制詳解及源碼分析
Android異步類AsyncTask詳解
轉(zhuǎn)載于:https://www.cnblogs.com/xs104/p/4869669.html
總結(jié)
以上是生活随笔為你收集整理的Android笔记(三十六) AsyncTask是如何执行的?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tinydate.js[v0.3] 新增
- 下一篇: 创建自已的sql函数