日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android总结 之 AsyncTask(二)

發布時間:2024/2/28 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android总结 之 AsyncTask(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先從AsyncTask的execute方法開始介紹,這是AsyncTask的入口:

public final AsyncTask<Params, Progress, Result> execute(Params... params) {return executeOnExecutor(sDefaultExecutor, params);}

執行的是他的重載函數executeOnExecutor,其中處理器Executor是sDefaultExecutor,我們先把它放在一邊,先看它的重載函數executeOnExecutor:

public 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;}

這里我們看到有每個任務有三個狀態PENDING,RUNNING和FINISHED,其中只有在任務是PENDING時,任務才會往下執行,并把任務的狀態設置成Running

public enum Status {// 表示task沒有運行PENDING,RUNNING,FINISHED,}

onPreExecute();是抽象函數,需要用戶去重寫。mWorker和mFuture是什么東東呢?繼續往下看。

mWorker = new WorkerRunnable<Params, Result>() {public Result call() throws Exception {mTaskInvoked.set(true);Result result = null;try {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//noinspection uncheckedresult = doInBackground(mParams);Binder.flushPendingCommands();} catch (Throwable tr) {mCancelled.set(true);throw tr;} finally {postResult(result);}return 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);}}};}

mWorker是WorkerRunnable的子類,WorkerRunnable只是一個添加了mParams的Callable,實現了Callable的類必須實現他的call方法,call方法能獲得并返回結果。將一個callable子類作為FutureTask的參數,可以接收運算的結果,這里FutureTask通過get方獲得結果,采用通知的方式,不會阻塞線程。

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {Params[] mParams;}

知道了這么多東西,可能有點亂了,這里講解到了這里:

//AsyncTask的executeOnExecutor方法mStatus = Status.RUNNING;onPreExecute();mWorker.mParams = params;//這里exec.execute(mFuture);return this;

exec.execute(mFuture); 這里是最重要的部分,我們先回頭看一下executeOnExecutor(sDefaultExecutor, params);中的sDefaultExecutor

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

從名字可以看出來,這是一個串行的執行器。

private static class SerialExecutor implements Executor {final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();Runnable mActive;public synchronized void execute(final Runnable r) {mTasks.offer(new Runnable() {public void run() {try {r.run();} finally {scheduleNext();}}});if (mActive == null) {scheduleNext();}}protected synchronized void scheduleNext() {if ((mActive = mTasks.poll()) != null) {THREAD_POOL_EXECUTOR.execute(mActive);}}}

我們可以大致了解到,mTasks是一個數組雙向隊列,這是一個環狀的數組,有興趣的同學可以看看。

SerialExecutor用于Runnable的調度,它將Runnable進行簡單的包裝,并保存到隊里中。經過包裝后,不僅會執行原始提交Runnable的代碼,并且會執行結束后用THREAD_POOL_EXECUTOR調用隊列中的下一個Runnable。這時候就要去思考了,THREAD_POOL_EXECUTOR是什么東東呢?

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;private static final int KEEP_ALIVE_SECONDS = 30;private static final ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1);public Thread newThread(Runnable r) {return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());}};private static final BlockingQueue<Runnable> sPoolWorkQueue =new LinkedBlockingQueue<Runnable>(128);/*** An {@link Executor} that can be used to execute tasks in parallel.*/public static final Executor THREAD_POOL_EXECUTOR;static {ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,sPoolWorkQueue, sThreadFactory);threadPoolExecutor.allowCoreThreadTimeOut(true);THREAD_POOL_EXECUTOR = threadPoolExecutor;}

從這里看出,這是一個線程池,也就是說SerialExecutor保證任務在隊列中的順序,然后自己一邊執行任務,一邊交給線程池THREAD_POOL_EXECUTOR執行,這是線程池是并行執行任務的:

好了,執行任務excute方法搞定了,那對于返回的結果,AsyncTask是怎么處理的呢?我們知道,回調這個操作是由Callable接口中的call()方法執行,通過 postResult(result);返回結果。

mWorker = new WorkerRunnable<Params, Result>() {public Result call() throws Exception {mTaskInvoked.set(true);Result result = null;try {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//noinspection uncheckedresult = doInBackground(mParams);Binder.flushPendingCommands();} catch (Throwable tr) {mCancelled.set(true);throw tr;} finally {postResult(result);}return result;}};

因為安卓的ui要在主線程中更新,postResult實際上就是新線程向主線程發送消息,讓主線程去更新ui。

private Result postResult(Result result) {@SuppressWarnings("unchecked")Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,new AsyncTaskResult<Result>(this, result));message.sendToTarget();return result;}

讓我們先看看這個Handler到底是什么東西。

private static Handler getMainHandler() {synchronized (AsyncTask.class) {if (sHandler == null) {sHandler = new InternalHandler(Looper.getMainLooper());}return sHandler;}}

可以看到這是一個AsyncTask的靜態內部類InternalHandler,看看它做了什么?

private static class InternalHandler extends Handler {public InternalHandler(Looper looper) {super(looper);}@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;}}}

可以看到,它定義了一個handleMessage方法,我們先賣個關子,知道它定義了一個handleMessaage方法。

繼續看回來PostResult方法:

private Result postResult(Result result) {@SuppressWarnings("unchecked")Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,new AsyncTaskResult<Result>(this, result));message.sendToTarget();return result;}

我們知道了Handler是InternalHandler,而且知道它繼承了Handler并重寫了一個handleMessaage方法,obtainMessage()方法是用來干什么的呢?

// Handler中的obtainMessage方法,調用了message的obtain并將自己的指針扔進去public final Message obtainMessage(int what, Object obj){return Message.obtain(this, what, obj);} // Message 中的Obtain方法public static Message obtain(Handler h, int what, Object obj) {Message m = obtain();m.target = h;m.what = what;m.obj = obj;return m;}

obtainMessage方法很簡單,只是用來構造一個Message對象而已,值得一提的是這個對象的target是handler

ok,我們拿到了一個Handler,并用Handler構造出了一個Message對象,接下來要怎么處理呢?看一下postResule的 message.sendToTarget()方法,最終調用了Handler的sendMessageAtTime方法

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {MessageQueue queue = mQueue;if (queue == null) {RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);return false;}return enqueueMessage(queue, msg, uptimeMillis);}

這里得到Handler里面的的mQueue隊列,并執行enqueueMessage方法,這里大家應該能猜到,它想把這個message作入隊列的操作把?驗證一下

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {msg.target = this;if (mAsynchronous) {msg.setAsynchronous(true);}return queue.enqueueMessage(msg, uptimeMillis);}

完成入隊之后,mQueue這個隊列同樣是Looper類的成員,我們可以猜想Looper就是用來遍歷queue的,來看看是不是

loop(){for (;;) {Message msg = queue.next(); // might blockif (msg == null) {// No message indicates that the message queue is quitting.return;}msg.target.dispatchMessage(msg);}}

果然是用來遍歷queue的,最后調用的是 msg.target.dispatchMessage(msg);方法,這時候我們聯想到上面message的Objtain方法,把當前hander作為Message的target,所以msg.target得到的就是處理這個message的handler。

public void dispatchMessage(Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}

dispactchMessage(mes)是InternalHandler中的方法,調用了它的唯一重寫的方法handleMessage。這就是我們當時看InternalHandler的那個伏筆,哈哈

那我們在回頭看看InternalHandler把!

private static class InternalHandler extends Handler {public InternalHandler(Looper looper) {super(looper);}@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;}}}

InternalHandler的handleMessage就是簡單的處理結果:最后調用finish方法,我們來看一下。

private void finish(Result result) {if (isCancelled()) {onCancelled(result);} else {onPostExecute(result);}mStatus = Status.FINISHED;}

最后調用了onPostExecute,也是重寫AsyncSTask可以選擇重寫的方法, 主要執行異步得到結果之后,主線程對ui的處理。

總結

以上是生活随笔為你收集整理的Android总结 之 AsyncTask(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 天堂网在线最新版www中文网 | 国产精品午夜一区二区 | wwwxxxx国产 | 国产视色 | 色妞色视频一区二区三区四区 | 国产高清www| 少妇太爽了在线观看 | 97超碰国产在线 | 69精品无码成人久久久久久 | 国产精品久久久久高潮 | 中文字幕 亚洲一区 | 国产一区二区在线免费观看 | 香蕉国产 | 国内免费精品视频 | 日韩精品第二页 | 一边吃奶一边摸做爽视频 | 善良的老师伦理bd中字 | 手机看片欧美日韩 | h视频免费在线观看 | 男女av| 男人在线网站 | 黄色仓库av | av基地网| 午夜精品福利一区二区三区蜜桃 | 秋霞中文字幕 | 无码人妻一区二区三区一 | 午夜福利视频 | 国产高清免费观看 | 一级视频在线免费观看 | 91麻豆精品一二三区在线 | www午夜视频 | 魔女鞋交玉足榨精调教 | 男人天堂网址 | jizzzz中国 | 人人干在线视频 | 欧美黄色录像视频 | 久久岛国 | 国产欧美一区二区精品性色 | 亚洲最新av | 91亚洲精品久久久蜜桃网站 | 久久国产精品久久国产精品 | 永久免费看mv网站入口亚洲 | 国产香蕉一区二区三区 | 日韩一级欧美一级 | 美女久久久久久久久 | www.国产在线视频 | 91精品国产成人观看 | av免费在线观 | 精品一区中文字幕 | 日韩久久一区二区 | 亚洲综合激情 | 色干网 | 国产精品成熟老女人 | 女人18毛片水真多18精品 | 国产77777 | 日本高清不卡码 | 好吊妞一区二区三区 | 黄色美女av | 欧美一区二区不卡视频 | 男人天堂新地址 | 欧美成人精品一区二区三区在线观看 | 久久精品网| 天堂中文在线视频 | 日日夜夜一区 | 在线国产日韩 | 亚洲一区二区视频 | 天天添天天操 | 亚洲激情中文 | 日韩欧美国产精品综合嫩v 国产小毛片 | 国产激情小视频 | 丰满少妇在线观看网站 | 国产精品999在线观看 | 免费观看nba乐趣影院 | 日韩网站免费观看 | 日韩在线视频你懂的 | 成人免费观看视频网站 | 日本激情一区二区三区 | 久久久久久亚洲av无码专区 | 精品一区二区三区免费毛片 | 99产精品成人啪免费网站 | 欧美高清大白屁股ass18 | 永久免费看片在线播放 | 亚洲区视频在线观看 | 日韩一区二区三区精品 | 天堂网中文在线观看 | 男同互操gay射视频在线看 | 人妻大战黑人白浆狂泄 | 美国黄色av| 浓精喷进老师黑色丝袜在线观看 | 欧美久久天堂 | 蜜臀av一区二区 | 色老头一区二区三区在线观看 | 欧美成人综合视频 | 国产精品综合视频 | 4444亚洲人成无码网在线观看 | 久久久天堂国产精品女人 | 精品一区二区三区视频 | 欧美在线一二三区 | 精品国产乱子伦一区二区 |