前言:
這一篇博文主要是和大家講解一下線程間通訊機制的內部實現原理,即Handler、Message、MessageQueue、Looper、HandlerThread、AsyncTask類的實現以及之間的關系。如果還沒有接觸過Handler+Message+Runnable、HandlerThread、AsyncTask的朋友可以先看看基礎篇:
【Android開發】線程間通訊機制(基礎篇)——Handler、Runnable、HandlerThread、AsyncTask的使用
有時候,如果你能帶著問題或者目標去探索新知識的話,這樣的學習效率就高很多。 所以我們先從最基礎的實現方式(Handler+Message+Runnable)說起。
一、Handler+Message+Runnable內部解析
問題:我們在使用Handler類的時候,都知道有sendMessage(Message)等發送消息的功能和 post(Runnable)發送任務的功能,然后還有能夠處理接受到的Message的功能。這時候我就會提出這樣的問題:
1、有發送、接受Message的功能,是不是sendMessage方法是直接調用handleMessage的重寫方法里呢?
2、不是有按時間計劃發送Message和Runnable嗎?如果問題1成立的話,handleMessage可能會同時接受多個 Message,但是此方法不是線程安全的(沒有synchronized修飾),這樣會出現問題了。
? ??
解決問題:如果對API有任何疑惑,最根本的方法就是查看源代碼。
在看源代碼之前,需要了解幾個類:
Handler:負責發送Message和Runnable到MessageQueue中,然后依次處理MessageQueue里面的隊列。
MessageQueue:消息隊列。負責存放一個線程的Message和Runnable的集合。
Message:消息實體類。
Looper:消息循環器。負責把MessageQueue中的Message或者Runnable循環取出來,然后分發到Handler中。
四者的關系:一個線程可以有多個Handler實例,一個線程對應一個Looper,一個Looper也只對應一個 MessageQueue,一個MessageQueue對應多個Message和Runnable。所以就形成了一對多的對應關系,一 方:線程、Looper、MessageQueue;多方:Handler、Message。同時可以看出另一個一對一關系:一個 Message實例對應一個Handler實例。
一個Handler實例都會與一個線程和消息隊列捆綁在一起,當實例化Handler的時候,就已經完成這樣的工作。源 碼如下:
Handler類
[java] view plain
copy ? ? ? ? ? ? ?? ????public ?Handler()?{?? ????????this (null ,?false );?? ????}??
[java] view plain
copy public ?Handler(Callback?callback,?boolean ?async)?{??????????if ?(FIND_POTENTIAL_LEAKS)?{?? ????????????final ?Class<??extends ?Handler>?klass?=?getClass();?? ????????????if ?((klass.isAnonymousClass()?||?klass.isMemberClass()?||?klass.isLocalClass())?&&?? ????????????????????(klass.getModifiers()?&?Modifier.STATIC)?==?0 )?{?? ????????????????Log.w(TAG,?"The?following?Handler?class?should?be?static?or?leaks?might?occur:?" ?+?? ????????????????????klass.getCanonicalName());?? ????????????}?? ????????}?? ?? ????????mLooper?=?Looper.myLooper();?? ????????if ?(mLooper?==?null )?{?? ????????????throw ?new ?RuntimeException(?? ????????????????"Can't?create?handler?inside?thread?that?has?not?called?Looper.prepare()" );?? ????????}?? ????????mQueue?=?mLooper.mQueue;?? ????????mCallback?=?callback;?? ????????mAsynchronous?=?async;?? ????}??
? 可以從mLooper = Looper.myLooper()
mQueue = mLooper.mQueue;看出,實例化Handler就會綁定一個Looper實例,并且一個Looper實例包涵一個 MessageQueue實例。
問題來了,為什么說一個線程對應一個Looper實例?我們通過Looper.myLooper()找原因:
Looper類
[java] view plain
copy ?? ???static ?final ?ThreadLocal<Looper>?sThreadLocal?=?new ?ThreadLocal<Looper>();??
[java] view plain
copy ? ? ? ?? ????public ?static ?Looper?myLooper()?{?? ????????return ?sThreadLocal.get();?? ????}??
ThreadLocal類
Implements a thread-local storage, that is, a variable for which each thread has its own value. All threads share the sameThreadLocal object, but each sees a different value when accessing it, and changes made by one thread do not affect the other threads. The implementation supportsnull values.
——實現一個線程本地的存儲,就是說每個線程都會有自己的內存空間來存放線程自己的值。所有線程都共享一 個ThreadLocal對象,但是不同的線程都會對應不同的value,而且單獨修改不影響其他線程的value,并且支持 null值。
所以說,每個線程都會存放一個獨立的Looper實例,通過ThreadLocal.get()方法,就會獲得當前線程的Looper的 實例。
好了,接下來就要研究一下Handler發送Runnable,究竟怎么發送?
Handler類:
[java] view plain
copy public ?final ?boolean ?post(Runnable?r)??????{?? ???????return ??sendMessageDelayed(getPostMessage(r),?0 );?? ????}??
[java] view plain
copy private ?static ?Message?getPostMessage(Runnable?r)?{??????????Message?m?=?Message.obtain();?? ????????m.callback?=?r;?? ????????return ?m;?? ????}??
可以看出,其實傳入的Runnable對象都是封裝到Message類中,看下Message是存放什么信息:
Message類:
[java] view plain
copy public ?final ?class ?Message?implements ?Parcelable?{????????public ?int ?what;???? ????public ?int ?arg1;???? ????public ?int ?arg2;???? ????public ?Object?obj;???? ????public ?Messenger?replyTo;???? ????long ?when;???? ????Bundle?data;???? ????Handler?target;????????? ????Runnable?callback;????? ????Message?next;???? ????private ?static ?Object?mPoolSync?=?new ?Object();???? ????private ?static ?Message?mPool;???? ????private ?static ?int ?mPoolSize?=?0 ;???? ????private ?static ?final ?int ?MAX_POOL_SIZE?=?10 ;???
When: 向Handler發送Message生成的時間 Data: 在Bundler 對象上綁定要線程中傳遞的數據 Next: 當前Message 對一下個Message 的引用 Handler: 處理當前Message 的Handler對象. mPool: 通過字面理解可能叫他Message池,但是通過分析應該叫有下一個Message引用的Message鏈更加適合. 其中Message.obtain(),通過源碼分析就是獲取斷掉Message鏈關系的第一個Message.
? ? ? ?對于源碼的解讀,可以明確兩點:
? ? ? ? 1)Message.obtain()是通過從全局Message pool中讀取一個Message,回收的時候也是將該Message 放入到 pool中。
? ? ? ? 2)Message中實現了Parcelable接口
所以接下來看下Handler如何發送Message:
Handler類
[java] view plain
copy ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ???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);?? ???}??
[java] view plain
copy private ?boolean ?enqueueMessage(MessageQueue?queue,?Message?msg,?long ?uptimeMillis)?{?????????msg.target?=?this ;?? ???????if ?(mAsynchronous)?{?? ???????????msg.setAsynchronous(true );?? ???????}?? ???????return ?queue.enqueueMessage(msg,?uptimeMillis);?? ???}??
其實無論是按時間計劃發送Message或者Runnable,最終是調用了sendMessageAtTime方法,里面核心執行的 是enqueueMessage方法,就是調用了MessageQueue中的enqueueMessage方法,就是把消息Message加入到 消息隊列中。
這時候問題又來了,如果發送消息只是把消息加入到消息隊列中,那誰來把消息分發到Handler中呢?
不妨我們看看Looper類:
[java] view plain
copy ? ? ? ?? ????public ?static ?void ?loop()?{?? ????????final ?Looper?me?=?myLooper();?? ????????if ?(me?==?null )?{?? ????????????throw ?new ?RuntimeException("No?Looper;?Looper.prepare()?wasn't?called?on?this?thread." );?? ????????}?? ????????final ?MessageQueue?queue?=?me.mQueue;?? ?? ?????????? ?????????? ????????Binder.clearCallingIdentity();?? ????????final ?long ?ident?=?Binder.clearCallingIdentity();?? ?? ????????for ?(;;)?{?? ????????????Message?msg?=?queue.next();??? ????????????if ?(msg?==?null )?{?? ?????????????????? ????????????????return ;?? ????????????}?? ?? ?????????????? ????????????Printer?logging?=?me.mLogging;?? ????????????if ?(logging?!=?null )?{?? ????????????????logging.println(">>>>>?Dispatching?to?" ?+?msg.target?+?"?" ?+?? ????????????????????????msg.callback?+?":?" ?+?msg.what);?? ????????????}?? ?? ????????????msg.target.<span?style="color:#ff0000;" ><strong>dispatchMessage</strong></span>(msg);?? ?? ????????????if ?(logging?!=?null )?{?? ????????????????logging.println("<<<<<?Finished?to?" ?+?msg.target?+?"?" ?+?msg.callback);?? ????????????}?? ?? ?????????????? ?????????????? ????????????final ?long ?newIdent?=?Binder.clearCallingIdentity();?? ????????????if ?(ident?!=?newIdent)?{?? ????????????????Log.wtf(TAG,?"Thread?identity?changed?from?0x" ?? ????????????????????????+?Long.toHexString(ident)?+?"?to?0x" ?? ????????????????????????+?Long.toHexString(newIdent)?+?"?while?dispatching?to?" ?? ????????????????????????+?msg.target.getClass().getName()?+?"?" ?? ????????????????????????+?msg.callback?+?"?what=" ?+?msg.what);?? ????????????}?? ?? ????????????msg.recycle();?? ????????}?? ????}??
里面loop方法找到調用Handler的dispatchMessage的方法,我們再看看Handler的dispatchMessage:
[java] view plain
copy public ?void ?dispatchMessage(Message?msg)?{?????????if ?(msg.callback?!=?null )?{?? ???????????handleCallback(msg);?? ???????}?else ?{?? ???????????if ?(mCallback?!=?null )?{?? ???????????????if ?(mCallback.handleMessage(msg))?{?? ???????????????????return ;?? ???????????????}?? ???????????}?? ???????????handleMessage(msg);?? ???????}?? ???}??
dispatchMessage最終是回調了handleMessage。換句話說,Loop的loop()方法就是取得當前線程中的 MessageQueue實例,然后不斷循環消息分發到對應的Handler實例上。就是只要調用Looper.loop()方法,就可 以執行消息分發。
小結:Handler、Message、MessageQueue、Looper的關系原理圖:
整個機制實現原理流程:當應用程序運行的時候,會創建一個主線程(UI線程)ActivityThread,這個類里面有個 main方法,就是java程序運行的最開始的入口
[java] view plain
copy public ?static ?void ?main(String[]?args)?{??????????SamplingProfilerIntegration.start();?? ?? ?????????? ?????????? ?????????? ????????CloseGuard.setEnabled(false );?? ?? ????????Process.setArgV0("<pre-initialized>" );?? ?? ????????Looper.prepareMainLooper();?? ????????if ?(sMainThreadHandler?==?null )?{?? ????????????sMainThreadHandler?=?new ?Handler();?? ????????}?? ?? ????????ActivityThread?thread?=?new ?ActivityThread();?? ????????thread.attach(false );?? ?? ????????if ?(false )?{?? ????????????Looper.myLooper().setMessageLogging(new ?? ????????????????????LogPrinter(Log.DEBUG,?"ActivityThread" ));?? ????????}?? ?? ????????<span?style="color:#ff0000;" >Looper.loop();</span>?? ?? ????????throw ?new ?RuntimeException("Main?thread?loop?unexpectedly?exited" );?? ????}??
UI線程就開始就已經調用了loop消息分發,所以當在UI線程實例的Handler對象發送消息或者任務時,會把 Message加入到MessageQueue消息隊列中,然后分發到Handler的handleMessage方法里。
二、HandlerThread
其實上述就是線程間通訊機制的實現,而HandlerThread和AsyncTask只是對通訊機制進行進一步的封裝,要理 解也很簡單:
HandlerThread類:
[java] view plain
copy public ?class ?HandlerThread?extends ?Thread?{??????int ?mPriority;?? ????int ?mTid?=?-1 ;?? ????Looper?mLooper;?? ?? ????public ?HandlerThread(String?name)?{?? ????????super (name);?? ????????mPriority?=?Process.THREAD_PRIORITY_DEFAULT;?? ????}?? ?????? ????? ? ? ? ? ?? ????public ?HandlerThread(String?name,?int ?priority)?{?? ????????super (name);?? ????????mPriority?=?priority;?? ????}?? ?????? ????? ? ? ?? ????protected ?void ?onLooperPrepared()?{?? ????}?? ?? ????public ?void ?run()?{?? ????????mTid?=?Process.myTid();?? ????????<span?style="color:#ff0000;" >Looper.prepare();</span>?? ????????synchronized ?(this )?{?? ????????????mLooper?=?Looper.myLooper();?? ????????????notifyAll();?? ????????}?? ????????Process.setThreadPriority(mPriority);?? ????????onLooperPrepared();?? ????????<span?style="color:#ff0000;" >Looper.loop();</span>?? ????????mTid?=?-1 ;?? ????}?? ?????? ????? ? ? ? ? ?? ????public ?Looper?getLooper()?{?? ????????if ?(!isAlive())?{?? ????????????return ?null ;?? ????????}?? ?????????? ?????????? ????????synchronized ?(this )?{?? ????????????while ?(isAlive()?&&?mLooper?==?null )?{?? ????????????????try ?{?? ????????????????????wait();?? ????????????????}?catch ?(InterruptedException?e)?{?? ????????????????}?? ????????????}?? ????????}?? ????????return ?mLooper;?? ????}?? ?????? ????? ? ? ? ? ?? ????public ?boolean ?quit()?{?? ????????Looper?looper?=?getLooper();?? ????????if ?(looper?!=?null )?{?? ????????????looper.quit();?? ????????????return ?true ;?? ????????}?? ????????return ?false ;?? ????}?? ?????? ????? ? ?? ????public ?int ?getThreadId()?{?? ????????return ?mTid;?? ????}?? }??
可以看得出,HandlerThread繼承了Thread,從run()方法可以看出,HandlerThread要嗲用start()方法,才能實例 化HandlerThread的Looper對象,和消息分發功能。
所以使用HandlerThread,必須先運行HandlerThread,才能取出對應的Looper對象,然后使用 Handler(Looper)構造方法實例Handler,這樣Handler的handleMessage方法就是子線程執行了。
三、AsyncTask
AsyncTask現在是android應用開發最常用的工具類,這個類面向調用者是輕量型的,但是對于系統性能來說是 重量型的。這個類很強大,使用者很方便就能使用,只需要在對應的方法實現特定的功能即可 。就是因為 AsyncTask的強大封裝,所以說不是輕量型的,先看下源代碼吧:
[java] view plain
copy public ?abstract ?class ?AsyncTask<Params,?Progress,?Result>?{??????private ?static ?final ?String?LOG_TAG?=?"AsyncTask" ;?? ?? ????private ?static ?final ?int ?CORE_POOL_SIZE?=?5 ;?? ????private ?static ?final ?int ?MAXIMUM_POOL_SIZE?=?128 ;?? ????private ?static ?final ?int ?KEEP_ALIVE?=?1 ;?? ?? ????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>(10 );?? ?? ????? ? ?? ????public ?static ?final ?Executor?THREAD_POOL_EXECUTOR?? ????????????=?new ?ThreadPoolExecutor(CORE_POOL_SIZE,?MAXIMUM_POOL_SIZE,?KEEP_ALIVE,?? ????????????????????TimeUnit.SECONDS,?sPoolWorkQueue,?sThreadFactory);?? ?? ????? ? ? ?? ????public ?static ?final ?Executor?SERIAL_EXECUTOR?=?new ?SerialExecutor();?? ?? ????private ?static ?final ?int ?MESSAGE_POST_RESULT?=?0x1 ;?? ????private ?static ?final ?int ?MESSAGE_POST_PROGRESS?=?0x2 ;?? ?? ????private ?static ?final ?InternalHandler?sHandler?=?new ?InternalHandler();?? ?? ????private ?static ?volatile ?Executor?sDefaultExecutor?=?SERIAL_EXECUTOR;?? ????private ?final ?WorkerRunnable<Params,?Result>?mWorker;?? ????private ?final ?FutureTask<Result>?mFuture;?? ?? ????private ?volatile ?Status?mStatus?=?Status.PENDING;?? ?????? ????private ?final ?AtomicBoolean?mCancelled?=?new ?AtomicBoolean();?? ????private ?final ?AtomicBoolean?mTaskInvoked?=?new ?AtomicBoolean();?? ?? ????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);?? ????????????}?? ????????}?? ????}?? ?? ????? ? ? ?? ????public ?enum ?Status?{?? ????????? ? ?? ????????PENDING,?? ????????? ? ?? ????????RUNNING,?? ????????? ? ?? ????????FINISHED,?? ????}?? ?? ?????? ????public ?static ?void ?init()?{?? ????????sHandler.getLooper();?? ????}?? ?? ?????? ????public ?static ?void ?setDefaultExecutor(Executor?exec)?{?? ????????sDefaultExecutor?=?exec;?? ????}?? ?? ????? ? ?? ????public ?AsyncTask()?{?? ????????mWorker?=?new ?WorkerRunnable<Params,?Result>()?{?? ????????????public ?Result?call()?throws ?Exception?{?? ????????????????mTaskInvoked.set(true );?? ?? ????????????????Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);?? ?????????????????? ????????????????return ?postResult(doInBackground(mParams));?? ????????????}?? ????????};?? ?? ????????mFuture?=?new ?FutureTask<Result>(mWorker)?{?? ????????????@Override ?? ????????????protected ?void ?done()?{?? ????????????????try ?{?? ????????????????????postResultIfNotInvoked(get());?? ????????????????}?catch ?(InterruptedException?e)?{?? ????????????????????android.util.Log.w(LOG_TAG,?e);?? ????????????????}?catch ?(ExecutionException?e)?{?? ????????????????????throw ?new ?RuntimeException("An?error?occured?while?executing?doInBackground()" ,?? ????????????????????????????e.getCause());?? ????????????????}?catch ?(CancellationException?e)?{?? ????????????????????postResultIfNotInvoked(null );?? ????????????????}?? ????????????}?? ????????};?? ????}?? ?? ????private ?void ?postResultIfNotInvoked(Result?result)?{?? ????????final ?boolean ?wasTaskInvoked?=?mTaskInvoked.get();?? ????????if ?(!wasTaskInvoked)?{?? ????????????postResult(result);?? ????????}?? ????}?? ?? ????private ?Result?postResult(Result?result)?{?? ????????@SuppressWarnings ("unchecked" )?? ????????Message?message?=?sHandler.obtainMessage(MESSAGE_POST_RESULT,?? ????????????????new ?AsyncTaskResult<Result>(this ,?result));?? ????????message.sendToTarget();?? ????????return ?result;?? ????}?? ?? ?????? ????public ?final ?Status?getStatus()?{?? ????????return ?mStatus;?? ????}?? ?? ?????? ????protected ?abstract ?Result?doInBackground(Params...?params);?? ?? ????? ????protected ?void ?onPreExecute()?{?? ????}?? ?? ?????? ????@SuppressWarnings ({"UnusedDeclaration" })?? ????protected ?void ?onPostExecute(Result?result)?{?? ????}?? ?? ?????? ????@SuppressWarnings ({"UnusedDeclaration" })?? ????protected ?void ?onProgressUpdate(Progress...?values)?{?? ????}?? ?? ????? ????@SuppressWarnings ({"UnusedParameters" })?? ????protected ?void ?onCancelled(Result?result)?{?? ????????onCancelled();?? ????}?????? ?????? ?????? ????protected ?void ?onCancelled()?{?? ????}?? ?? ?????? ????public ?final ?boolean ?isCancelled()?{?? ????????return ?mCancelled.get();?? ????}?? ?? ?????? ????public ?final ?boolean ?cancel(boolean ?mayInterruptIfRunning)?{?? ????????mCancelled.set(true );?? ????????return ?mFuture.cancel(mayInterruptIfRunning);?? ????}?? ?? ?????? ????public ?final ?Result?get()?throws ?InterruptedException,?ExecutionException?{?? ????????return ?mFuture.get();?? ????}?? ?? ?????? ????public ?final ?Result?get(long ?timeout,?TimeUnit?unit)?throws ?InterruptedException,?? ????????????ExecutionException,?TimeoutException?{?? ????????return ?mFuture.get(timeout,?unit);?? ????}?? ?? ?????? ????public ?final ?AsyncTask<Params,?Progress,?Result>?execute(Params...?params)?{?? ????????return ?executeOnExecutor(sDefaultExecutor,?params);?? ????}?? ?? ????? ????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 ;?? ????}?? ?? ?????? ????public ?static ?void ?execute(Runnable?runnable)?{?? ????????sDefaultExecutor.execute(runnable);?? ????}?? ?? ?????? ????protected ?final ?void ?publishProgress(Progress...?values)?{?? ????????if ?(!isCancelled())?{?? ????????????sHandler.obtainMessage(MESSAGE_POST_PROGRESS,?? ????????????????????new ?AsyncTaskResult<Progress>(this ,?values)).sendToTarget();?? ????????}?? ????}?? ?? ????private ?void ?finish(Result?result)?{?? ????????if ?(isCancelled())?{?? ????????????onCancelled(result);?? ????????}?else ?{?? ????????????onPostExecute(result);?? ????????}?? ????????mStatus?=?Status.FINISHED;?? ????}?? ?? ????private ?static ?class ?InternalHandler?extends ?Handler?{?? ????????@SuppressWarnings ({"unchecked" ,?"RawUseOfParameterizedType" })?? ????????@Override ?? ????????public ?void ?handleMessage(Message?msg)?{?? ????????????AsyncTaskResult?result?=?(AsyncTaskResult)?msg.obj;?? ????????????switch ?(msg.what)?{?? ????????????????case ?MESSAGE_POST_RESULT:?? ?????????????????????? ????????????????????result.mTask.finish(result.mData[0 ]);?? ????????????????????break ;?? ????????????????case ?MESSAGE_POST_PROGRESS:?? ????????????????????result.mTask.onProgressUpdate(result.mData);?? ????????????????????break ;?? ????????????}?? ????????}?? ????}?? ?? ????private ?static ?abstract ?class ?WorkerRunnable<Params,?Result>?implements ?Callable<Result>?{?? ????????Params[]?mParams;?? ????}?? ?? ????@SuppressWarnings ({"RawUseOfParameterizedType" })?? ????private ?static ?class ?AsyncTaskResult<Data>?{?? ????????final ?AsyncTask?mTask;?? ????????final ?Data[]?mData;?? ?? ????????AsyncTaskResult(AsyncTask?task,?Data...?data)?{?? ????????????mTask?=?task;?? ????????????mData?=?data;?? ????????}?? ????}?? }??
要理解這個工具類,主要是理解這幾個成員對象:
private static final InternalHandler sHandler = new InternalHandler();
? ? private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
? ? private final WorkerRunnable<Params, Result> mWorker;
? ? private final FutureTask<Result> mFuture;
分析:sHandler
消息的發送者和處理者
? sDefualtExecutor
線程執行者。實際上就是一個線程池。
? mWorker
WorkerRunnable實現了Callable 接口,就是有返回值的線程任務。
?mFuture
FutureTask是對Callable執行的一個管理類,能夠獲得線程執行返回的結果,和取消執行等操作。我們再深 入一下FutureTask,其中的done()方法是回調方法:
[java] view plain
copy ? ? ? ?? ?private ?void ?finishCompletion()?{?? ??????? ?????for ?(WaitNode?q;?(q?=?waiters)?!=?null ;)?{?? ?????????if ?(UNSAFE.compareAndSwapObject(this ,?waitersOffset,?q,?null ))?{?? ?????????????for ?(;;)?{?? ?????????????????Thread?t?=?q.thread;?? ?????????????????if ?(t?!=?null )?{?? ?????????????????????q.thread?=?null ;?? ?????????????????????LockSupport.unpark(t);?? ?????????????????}?? ?????????????????WaitNode?next?=?q.next;?? ?????????????????if ?(next?==?null )?? ?????????????????????break ;?? ?????????????????q.next?=?null ;??? ?????????????????q?=?next;?? ?????????????}?? ?????????????break ;?? ?????????}?? ?????}?? ?? ????<span?style="color:#cc0000;" >?done();</span>?? ?? ?????callable?=?null ;?????????? ?}??
只要線程移除或者掛起(取消)的時候,就會調用done()方法,然后在 AsyncTask類中的mTask實現了done()方 法,最后回調onCancelled()方法。
具體的流程原理是這樣的:
1、當第一次AsyncTask在UI線程實例化,其實是實例化Handler,同時UI線程的Looper和MessageQueue綁定在 sHandler對象中,之后再去實例話AsyncTask不會在初始化Handler,因為sHandler是類變量。
2、當執行execute方法的時候,實際上是調用線程池的execute方法運行線程
3、callable線程執行體就是調用了doInBackground(mParams)方法,然后以返回結果result當參數,又調用 postResult(Result result),實際上就是利用sHandler來發送result到UI線程的MessageQueue中,最后sHandler 接受到result后,回調onPostExecute方法。
4、如果主動調用publishProgress(Progress... values)方法,就會利用sHandler把value發送到UI線程的 MessageQueue中,然后sHandler接收到value后,回調onProgressUpdate(Progress... values)方法。
注意:sHandler和mDefaultExecutor是類變量
? mWorker和mFuture是實例變量
所以,無論進程中生成多少個AysncTask對象,sHandler和mDefaultExecutor都是同一個,只是任務不同而已。
四、總結
由于我放上去的源代碼刪除了一些注釋,如果還不能了解清楚的話,可以自行去源代碼上觀看。線程間通訊機制的核心就是Handler+Message+Looper+MessageQueue,只要理解這個四者的實現原理,再多的封裝好的工具類也難理解。所以,必須記住一點:android應用開發多線程是必不可少的,所以我們必須遵循UI線程模式開發,就是所有耗時不能在UI線程執行,操作UI必須在UI線程中執行。
原文地址: http://blog.csdn.net/q376420785/article/details/8883008
總結
以上是生活随笔 為你收集整理的线程间通讯机制(提高篇)——深入浅出实现原理 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。