真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android主線程,android主線程和子線程

Android進(jìn)程間和線程間通信方式

? 進(jìn)程:是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。

成都創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、蘭山網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開(kāi)發(fā)商城系統(tǒng)網(wǎng)站開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為蘭山等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。

??線程:是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。線程自己基本上不擁有系統(tǒng)資源,只擁有一些在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源。

??區(qū)別:

??(1)、一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程;

??(2)、線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高;

??(3)、進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,但線程之間沒(méi)有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉。

---------------------

一、Android進(jìn)程間通信方式

1.Bundle

??由于Activity,Service,Receiver都是可以通過(guò)Intent來(lái)攜帶Bundle傳輸數(shù)據(jù)的,所以我們可以在一個(gè)進(jìn)程中通過(guò)Intent將攜帶數(shù)據(jù)的Bundle發(fā)送到另一個(gè)進(jìn)程的組件。

??缺點(diǎn):無(wú)法傳輸Bundle不支持的數(shù)據(jù)類型。

2.ContentProvider

??ContentProvider是Android四大組件之一,以表格的方式來(lái)儲(chǔ)存數(shù)據(jù),提供給外界,即Content Provider可以跨進(jìn)程訪問(wèn)其他應(yīng)用程序中的數(shù)據(jù)。用法是繼承ContentProvider,實(shí)現(xiàn)onCreate,query,update,insert,delete和getType方法,onCreate是負(fù)責(zé)創(chuàng)建時(shí)做一些初始化的工作,增刪查改的方法就是對(duì)數(shù)據(jù)的查詢和修改,getType是返回一個(gè)String,表示Uri請(qǐng)求的類型。注冊(cè)完后就可以使用ContentResolver去請(qǐng)求指定的Uri。

3.文件

??兩個(gè)進(jìn)程可以到同一個(gè)文件去交換數(shù)據(jù),我們不僅可以保存文本文件,還可以將對(duì)象持久化到文件,從另一個(gè)文件恢復(fù)。要注意的是,當(dāng)并發(fā)讀/寫(xiě)時(shí)可能會(huì)出現(xiàn)并發(fā)的問(wèn)題。

4.Broadcast

??Broadcast可以向android系統(tǒng)中所有應(yīng)用程序發(fā)送廣播,而需要跨進(jìn)程通訊的應(yīng)用程序可以監(jiān)聽(tīng)這些廣播。

5.AIDL方式

??Service和Content Provider類似,也可以訪問(wèn)其他應(yīng)用程序中的數(shù)據(jù),Content Provider返回的是Cursor對(duì)象,而Service返回的是Java對(duì)象,這種可以跨進(jìn)程通訊的服務(wù)叫AIDL服務(wù)。

? ? ?AIDL通過(guò)定義服務(wù)端暴露的接口,以提供給客戶端來(lái)調(diào)用,AIDL使服務(wù)器可以并行處理,而Messenger封裝了AIDL之后只能串行運(yùn)行,所以Messenger一般用作消息傳遞。

6.Messenger

??Messenger是基于AIDL實(shí)現(xiàn)的,服務(wù)端(被動(dòng)方)提供一個(gè)Service來(lái)處理客戶端(主動(dòng)方)連接,維護(hù)一個(gè)Handler來(lái)創(chuàng)建Messenger,在onBind時(shí)返回Messenger的binder。

??雙方用Messenger來(lái)發(fā)送數(shù)據(jù),用Handler來(lái)處理數(shù)據(jù)。Messenger處理數(shù)據(jù)依靠Handler,所以是串行的,也就是說(shuō),Handler接到多個(gè)message時(shí),就要排隊(duì)依次處理。

7.Socket

??Socket方法是通過(guò)網(wǎng)絡(luò)來(lái)進(jìn)行數(shù)據(jù)交換,注意的是要在子線程請(qǐng)求,不然會(huì)堵塞主線程??蛻舳撕头?wù)端建立連接之后即可不斷傳輸數(shù)據(jù),比較適合實(shí)時(shí)的數(shù)據(jù)傳輸

二、Android線程間通信方式

??一般說(shuō)線程間通信主要是指主線程(也叫UI線程)和子線程之間的通信,主要有以下兩種方式:

1.AsyncTask機(jī)制

??AsyncTask,異步任務(wù),也就是說(shuō)在UI線程運(yùn)行的時(shí)候,可以在后臺(tái)的執(zhí)行一些異步的操作;AsyncTask可以很容易且正確地使用UI線程,AsyncTask允許進(jìn)行后臺(tái)操作,并在不顯示使用工作線程或Handler機(jī)制的情況下,將結(jié)果反饋給UI線程。但是AsyncTask只能用于短時(shí)間的操作(最多幾秒就應(yīng)該結(jié)束的操作),如果需要長(zhǎng)時(shí)間運(yùn)行在后臺(tái),就不適合使用AsyncTask了,只能去使用Java提供的其他API來(lái)實(shí)現(xiàn)。

2.Handler機(jī)制

??Handler,繼承自O(shè)bject類,用來(lái)發(fā)送和處理Message對(duì)象或Runnable對(duì)象;Handler在創(chuàng)建時(shí)會(huì)與當(dāng)前所在的線程的Looper對(duì)象相關(guān)聯(lián)(如果當(dāng)前線程的Looper為空或不存在,則會(huì)拋出異常,此時(shí)需要在線程中主動(dòng)調(diào)用Looper.prepare()來(lái)創(chuàng)建一個(gè)Looper對(duì)象)。使用Handler的主要作用就是在后面的過(guò)程中發(fā)送和處理Message對(duì)象和讓其他的線程完成某一個(gè)動(dòng)作(如在工作線程中通過(guò)Handler對(duì)象發(fā)送一個(gè)Message對(duì)象,讓UI線程進(jìn)行UI的更新,然后UI線程就會(huì)在MessageQueue中得到這個(gè)Message對(duì)象(取出Message對(duì)象是由其相關(guān)聯(lián)的Looper對(duì)象完成的),并作出相應(yīng)的響應(yīng))。

三、Android兩個(gè)子線程之間通信

??面試的過(guò)程中,有些面試官可能會(huì)問(wèn)Android子線程之間的通信方式,由于絕大部分程序員主要關(guān)注的是Android主線程和子線程之間的通信,所以這個(gè)問(wèn)題很容易讓人懵逼。

??主線程和子線程之間的通信可以通過(guò)主線程中的handler把子線程中的message發(fā)給主線程中的looper,或者,主線程中的handler通過(guò)post向looper中發(fā)送一個(gè)runnable。但looper默認(rèn)存在于main線程中,子線程中沒(méi)有Looper,該怎么辦呢?其實(shí)原理很簡(jiǎn)單,把looper綁定到子線程中,并且創(chuàng)建一個(gè)handler。在另一個(gè)線程中通過(guò)這個(gè)handler發(fā)送消息,就可以實(shí)現(xiàn)子線程之間的通信了。

??子線程創(chuàng)建handler的兩種方式:

??方式一:給子線程創(chuàng)建Looper對(duì)象:

new Thread(new Runnable() {

? ? ? ? public void run() {?

? ? ? ? ? ? Looper.prepare();? // 給這個(gè)Thread創(chuàng)建Looper對(duì)象,一個(gè)Thead只有一個(gè)Looper對(duì)象

? ? ? ? ? ? Handler handler = new Handler(){?

? ? ? ? ? ? ? ? @Override?

? ? ? ? ? ? ? ? public void handleMessage(Message msg) {?

? ? ? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();?

? ? ? ? ? ? ? ? }?

? ? ? ? ? ? };?

? ? ? ? ? ? handler.sendEmptyMessage(1);?

? ? ? ? ? ? Looper.loop(); // 不斷遍歷MessageQueue中是否有消息

? ? ? ? };?

? ? }).start();

---------------------

? ?方式二:獲取主線程的looper,或者說(shuō)是UI線程的looper:

new Thread(new Runnable() {

? ? ? ? public void run() {?

? ? ? ? ? ? Handler handler = new Handler(Looper.getMainLooper()){ // 區(qū)別在這!??!?

? ? ? ? ? ? ? ? @Override?

? ? ? ? ? ? ? ? public void handleMessage(Message msg) {?

? ? ? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();?

? ? ? ? ? ? ? ? }?

? ? ? ? ? ? };?

? ? ? ? ? ? handler.sendEmptyMessage(1);?

? ? ? ? };?

? ? }).start();

---------------------

android線程及handler的關(guān)系

handler是android特有的機(jī)制,最大的好處就是實(shí)現(xiàn)了Activity主線程(就是UI主線程)和其他線程(自己定義的Thread)之間的數(shù)據(jù)通信。Timer和Thread是實(shí)現(xiàn)多線程的,而handler是實(shí)現(xiàn)線程間通信的,二者很大不同,關(guān)于handler的用法

Android 中的“子線程”解析

Android 中線程可分為 主線程 和 子線程 兩類,其中主線程也就是 UI線程 ,它的主要這作用就是運(yùn)行四大組件、處理界面交互。子線程則主要是處理耗時(shí)任務(wù),也是我們要重點(diǎn)分析的。

首先 Java 中的各種線程在 Android 里是通用的,Android 特有的線程形態(tài)也是基于 Java 的實(shí)現(xiàn)的,所以有必要先簡(jiǎn)單的了解下 Java 中的線程,本文主要包括以下內(nèi)容:

在 Java 中要?jiǎng)?chuàng)建子線程可以直接繼承 Thread 類,重寫(xiě) run() 方法:

或者實(shí)現(xiàn) Runnable 接口,然后用Thread執(zhí)行Runnable,這種方式比較常用:

簡(jiǎn)單的總結(jié)下:

Callable 和 Runnable 類似,都可以用來(lái)處理具體的耗時(shí)任務(wù)邏輯的,但是但具體的差別在哪里呢?看一個(gè)小例子:

定義 MyCallable 實(shí)現(xiàn)了 Callable 接口,和之前 Runnable 的 run() 方法對(duì)比下, call() 方法是有返回值的哦,泛型就是返回值的類型:

一般會(huì)通過(guò)線程池來(lái)執(zhí)行 Callable (線程池相關(guān)內(nèi)容后邊會(huì)講到),執(zhí)行結(jié)果就是一個(gè) Future 對(duì)象:

可以看到,通過(guò)線程池執(zhí)行 MyCallable 對(duì)象返回了一個(gè) Future 對(duì)象,取出執(zhí)行結(jié)果。

Future 是一個(gè)接口,從其內(nèi)部的方法可以看出它提供了取消任務(wù)(有坑?。。。?、判斷任務(wù)是否完成、獲取任務(wù)結(jié)果的功能:

Future 接口有一個(gè) FutureTask 實(shí)現(xiàn)類,同時(shí) FutureTask 也實(shí)現(xiàn)了 Runnable 接口,并提供了兩個(gè)構(gòu)造函數(shù):

用 FutureTask 一個(gè)參數(shù)的構(gòu)造函數(shù)來(lái)改造下上邊的例子:

FutureTask 內(nèi)部有一個(gè) done() 方法,代表 Callable 中的任務(wù)已經(jīng)結(jié)束,可以用來(lái)獲取執(zhí)行結(jié)果:

所以 Future + Callable 的組合可以更方便的獲取子線程任務(wù)的執(zhí)行結(jié)果,更好的控制任務(wù)的執(zhí)行,主要的用法先說(shuō)這么多了,其實(shí) AsyncTask 內(nèi)部也是類似的實(shí)現(xiàn)!

注意, Future 并不能取消掉運(yùn)行中的任務(wù),這點(diǎn)在后邊的 AsyncTask 解析中有提到。

Java 中線程池的具體的實(shí)現(xiàn)類是 ThreadPoolExecutor ,繼承了 Executor 接口,這些線程池在 Android 中也是通用的。使用線程池的好處:

常用的構(gòu)造函數(shù)如下:

一個(gè)常規(guī)線程池可以按照如下方式來(lái)實(shí)現(xiàn):

執(zhí)行任務(wù):

基于 ThreadPoolExecutor ,系統(tǒng)擴(kuò)展了幾類具有新特性的線程池:

線程池可以通過(guò) execute() 、 submit() 方法開(kāi)始執(zhí)行任務(wù),主要差別從方法的聲明就可以看出,由于 submit() 有返回值,可以方便得到任務(wù)的執(zhí)行結(jié)果:

要關(guān)閉線程池可以使用如下方法:

IntentService 是 Android 中一種特殊的 Service,可用于執(zhí)行后臺(tái)耗時(shí)任務(wù),任務(wù)結(jié)束時(shí)會(huì)自動(dòng)停止,由于屬于系統(tǒng)的四大組件之一,相比一般線程具有較高的優(yōu)先級(jí),不容易被殺死。用法和普通 Service 基本一致,只需要在 onHandleIntent() 中處理耗時(shí)任務(wù)即可:

至于 HandlerThread,它是 IntentService 內(nèi)部實(shí)現(xiàn)的重要部分,細(xì)節(jié)內(nèi)容會(huì)在 IntentService 源碼中說(shuō)到。

IntentService 首次創(chuàng)建被啟動(dòng)的時(shí)候其生命周期方法 onCreate() 會(huì)先被調(diào)用,所以我們從這個(gè)方法開(kāi)始分析:

這里出現(xiàn)了 HandlerThread 和 ServiceHandler 兩個(gè)類,先搞明白它們的作用,以便后續(xù)的分析。

首先看 HandlerThread 的核心實(shí)現(xiàn):

首先它繼承了 Thread 類,可以當(dāng)做子線程來(lái)使用,并在 run() 方法中創(chuàng)建了一個(gè)消息循環(huán)系統(tǒng)、開(kāi)啟消息循環(huán)。

ServiceHandler 是 IntentService 的內(nèi)部類,繼承了 Handler,具體內(nèi)容后續(xù)分析:

現(xiàn)在回過(guò)頭來(lái)看 onCreate() 方法主要是一些初始化的操作, 首先創(chuàng)建了一個(gè) thread 對(duì)象,并啟動(dòng)線程,然后用其內(nèi)部的 Looper 對(duì)象 創(chuàng)建一個(gè) mServiceHandler 對(duì)象,將子線程的 Looper 和 ServiceHandler 建立了綁定關(guān)系,這樣就可以使用 mServiceHandler 將消息發(fā)送到子線程去處理了。

生命周期方法 onStartCommand() 方法會(huì)在 IntentService 每次被啟動(dòng)時(shí)調(diào)用,一般會(huì)這里處理啟動(dòng) IntentService 傳遞 Intent 解析攜帶的數(shù)據(jù):

又調(diào)用了 start() 方法:

就是用 mServiceHandler 發(fā)送了一條包含 startId 和 intent 的消息,消息的發(fā)送還是在主線程進(jìn)行的,接下來(lái)消息的接收、處理就是在子線程進(jìn)行的:

當(dāng)接收到消息時(shí),通過(guò) onHandleIntent() 方法在子線程處理 intent 對(duì)象, onHandleIntent() 方法執(zhí)行結(jié)束后,通過(guò) stopSelf(msg.arg1) 等待所有消息處理完畢后終止服務(wù)。

為什么消息的處理是在子線程呢?這里涉及到 Handler 的內(nèi)部消息機(jī)制,簡(jiǎn)單的說(shuō),因?yàn)?ServiceHandler 使用的 Looper 對(duì)象就是在 HandlerThread 這個(gè)子線程類里創(chuàng)建的,并通過(guò) Looper.loop() 開(kāi)啟消息循環(huán),不斷從消息隊(duì)列(單鏈表)中取出消息,并執(zhí)行,截取 loop() 的部分源碼:

dispatchMessage() 方法間接會(huì)調(diào)用 handleMessage() 方法,所以最終 onHandleIntent() 就在子線程中劃線執(zhí)行了,即 HandlerThread 的 run() 方法。

這就是 IntentService 實(shí)現(xiàn)的核心,通過(guò) HandlerThread + Hanlder 把啟動(dòng) IntentService 的 Intent 從主線程切換到子線程,實(shí)現(xiàn)讓 Service 可以處理耗時(shí)任務(wù)的功能!

AsyncTask 是 Android 中輕量級(jí)的異步任務(wù)抽象類,它的內(nèi)部主要由線程池以及 Handler 實(shí)現(xiàn),在線程池中執(zhí)行耗時(shí)任務(wù)并把結(jié)果通過(guò) Handler 機(jī)制中轉(zhuǎn)到主線程以實(shí)現(xiàn)UI操作。典型的用法如下:

從 Android3.0 開(kāi)始,AsyncTask 默認(rèn)是串行執(zhí)行的:

如果需要并行執(zhí)行可以這么做:

AsyncTask 的源碼不多,還是比較容易理解的。根據(jù)上邊的用法,可以從 execute() 方法開(kāi)始我們的分析:

看到 @MainThread 注解了嗎?所以 execute() 方法需要在主線程執(zhí)行哦!

進(jìn)而又調(diào)用了 executeOnExecutor() :

可以看到,當(dāng)任務(wù)正在執(zhí)行或者已經(jīng)完成,如果又被執(zhí)行會(huì)拋出異常!回調(diào)方法 onPreExecute() 最先被執(zhí)行了。

傳入的 sDefaultExecutor 參數(shù),是一個(gè)自定義的串行線程池對(duì)象,所有任務(wù)在該線程池中排隊(duì)執(zhí)行:

可以看到 SerialExecutor 線程池僅用于任務(wù)的排隊(duì), THREAD_POOL_EXECUTOR 線程池才是用于執(zhí)行真正的任務(wù),就是我們線程池部分講到的 ThreadPoolExecutor :

再回到 executeOnExecutor() 方法中,那么 exec.execute(mFuture) 就是觸發(fā)線程池開(kāi)始執(zhí)行任務(wù)的操作了。

那 executeOnExecutor() 方法中的 mWorker 是什么? mFuture 是什么?答案在 AsyncTask 的構(gòu)造函數(shù)中:

原來(lái) mWorker 是一個(gè) Callable 對(duì)象, mFuture 是一個(gè) FutureTask 對(duì)象,繼承了 Runnable 接口。所以 mWorker 的 call() 方法會(huì)在 mFuture 的 run() 方法中執(zhí)行,所以 mWorker 的 call() 方法在線程池得到執(zhí)行!

同時(shí) doInBackground() 方法就在 call() 中方法,所以我們自定義的耗時(shí)任務(wù)邏輯得到執(zhí)行,不就是我們第二部分講的那一套嗎!

doInBackground() 的返回值會(huì)傳遞給 postResult() 方法:

就是通過(guò) Handler 將最終的耗時(shí)任務(wù)結(jié)果從子線程發(fā)送到主線程,具體的過(guò)程是這樣的, getHandler() 得到的就是 AsyncTask 構(gòu)造函數(shù)中初始化的 mHandler , mHander 又是通過(guò) getMainHandler() 賦值的:

可以在看到 sHandler 是一個(gè) InternalHandler 類對(duì)象:

所以 getHandler() 就是在得到在主線程創(chuàng)建的 InternalHandler 對(duì)象,所以

就可以完成耗時(shí)任務(wù)結(jié)果從子線程到主線程的切換,進(jìn)而可以進(jìn)行相關(guān)UI操作了。

當(dāng)消息是 MESSAGE_POST_RESULT 時(shí),代表任務(wù)執(zhí)行完成, finish() 方法被調(diào)用:

如果任務(wù)沒(méi)有被取消的話執(zhí)行 onPostExecute() ,否則執(zhí)行 onCancelled() 。

如果消息是 MESSAGE_POST_PROGRESS , onProgressUpdate() 方法被執(zhí)行,根據(jù)之前的用法可以 onProgressUpdate() 的執(zhí)行需要我們手動(dòng)調(diào)用 publishProgress() 方法,就是通過(guò) Handler 來(lái)發(fā)送進(jìn)度數(shù)據(jù):

進(jìn)行中的任務(wù)如何取消呢?AsyncTask 提供了一個(gè) cancel(boolean mayInterruptIfRunning) ,參數(shù)代表是否中斷正在執(zhí)行的線程任務(wù),但是呢并不靠譜, cancel() 的方法注釋中有這么一段:

大致意思就是調(diào)用 cancel() 方法后, onCancelled(Object) 回調(diào)方法會(huì)在 doInBackground() 之后被執(zhí)行而 onPostExecute() 將不會(huì)被執(zhí)行,同時(shí)你應(yīng)該 doInBackground() 回調(diào)方法中通過(guò) isCancelled() 來(lái)檢查任務(wù)是否已取消,進(jìn)而去終止任務(wù)的執(zhí)行!

所以只能自己動(dòng)手了:

AsyncTask 整體的實(shí)現(xiàn)流程就這些了,源碼是最好的老師,自己跟著源碼走一遍有些問(wèn)題可能就豁然開(kāi)朗了!

Android線程優(yōu)先級(jí)和進(jìn)程oom_adj

在處理app啟動(dòng)速度的時(shí)候,可以設(shè)置主線程的優(yōu)先級(jí),保證主線程占用的cpu足夠久。進(jìn)程的oom_adj,決定了當(dāng)內(nèi)存不夠的時(shí)候,lmk會(huì)根據(jù)oom_adj的大小依次釋放內(nèi)存。

android中對(duì)線程等級(jí)劃分如下:

設(shè)置線程的優(yōu)先級(jí)分為:android 提供的api和java sdk自帶的api

注意: 要使用android提供的api設(shè)置,用java提供的作用不夠顯著

作用: 可以在主線程設(shè)置主線層等級(jí);在Glide加載圖片的時(shí)候設(shè)置低優(yōu)先級(jí)。當(dāng)圖片量很大的時(shí)候可以降低加載圖片線程的等級(jí)

android內(nèi)存不夠了,會(huì)觸發(fā)oom機(jī)制,lowMemoryKiller會(huì)根據(jù)每個(gè)進(jìn)程的oom_adj的等級(jí),依次殺死進(jìn)程,釋放內(nèi)存。

lom會(huì)根據(jù)free的內(nèi)存的值,來(lái)判斷kill掉哪個(gè)等級(jí)下的進(jìn)程。例如當(dāng)空閑內(nèi)存只有64M了。會(huì)kill掉oom_adj 為12-15的進(jìn)程

真實(shí)案例:應(yīng)用A跳到第三方應(yīng)用B,在第三方應(yīng)用B中播放視頻,加載大量圖片,導(dǎo)致返回的時(shí)候,應(yīng)用A走了SplashActivity。通過(guò)logcat發(fā)現(xiàn)A應(yīng)用被kill掉了

Android的handler機(jī)制的原理?

Android的handler機(jī)制的原理分為異步通信準(zhǔn)備,消息發(fā)送,消息循環(huán),消息處理。

1、異步通信準(zhǔn)備

在主線程中創(chuàng)建處理器對(duì)象(Looper)、?消息隊(duì)列對(duì)象(Message Queue)和Handler對(duì)象。

2、消息入隊(duì)

工作線程通過(guò)Handler發(fā)送消息(Message) 到消息隊(duì)列(Message Queue)中。

3、消息循環(huán)

消息出隊(duì): Looper循環(huán)取出消息隊(duì)列(Message Queue) 中的的消息(Message)。

消息分發(fā): Looper將取出的消息 (Message) 發(fā)送給創(chuàng)建該消息的處理者(Handler)。

4、消息處理

處理者(Handler) 接收處理器(Looper) 發(fā)送過(guò)來(lái)的消息(Message),根據(jù)消息(Message) 進(jìn)行U操作。

handler的作用

handler是android線程之間的消息機(jī)制,主要的作用是將一個(gè)任務(wù)切換到指定的線程中去執(zhí)行,(準(zhǔn)確的說(shuō)是切換到構(gòu)成handler的looper所在的線程中去出處理)android系統(tǒng)中的一個(gè)例子就是主線程中的所有操作都是通過(guò)主線程中的handler去處理的。

Handler的運(yùn)行需要底層的 messagequeue和 looper做支撐。

android 主線程和子線程有什么區(qū)別

具體如下:

在一個(gè)Android 程序開(kāi)始運(yùn)行的時(shí)候,會(huì)單獨(dú)啟動(dòng)一個(gè)Process。默認(rèn)的情況下,所有這個(gè)程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的兩種,除此之外還有Content Provider和Broadcast Receiver)都會(huì)跑在這個(gè)Process。

一個(gè)Android 程序默認(rèn)情況下也只有一個(gè)Process,但一個(gè)Process下卻可以有許多個(gè)Thread。在這么多Thread當(dāng)中,有一個(gè)Thread,我們稱之為UI Thread。UI Thread在Android程序運(yùn)行的時(shí)候就被創(chuàng)建,是一個(gè)Process當(dāng)中的主線程Main Thread,主要是負(fù)責(zé)控制UI界面的顯示、更新和控件交互。在Android程序創(chuàng)建之初,一個(gè)Process呈現(xiàn)的是單線程模型,所有的任務(wù)都在一個(gè)線程中運(yùn)行。因此,我們認(rèn)為,UI Thread所執(zhí)行的每一個(gè)函數(shù),所花費(fèi)的時(shí)間都應(yīng)該是越短越好。而其他比較費(fèi)時(shí)的工作(訪問(wèn)網(wǎng)絡(luò),下載數(shù)據(jù),查詢數(shù)據(jù)庫(kù)等),都應(yīng)該交由子線程去執(zhí)行,以免阻塞主線程。

那么,UI Thread如何和其他Thread一起工作呢?常用方法是:誕生一個(gè)主線程的Handler物件,當(dāng)做Listener去讓子線程能將訊息Push到主線程的Message Quene里,以便觸發(fā)主線程的handlerMessage()函數(shù),讓主線程知道子線程的狀態(tài),并在主線程更新UI。

例如,在子線程的狀態(tài)發(fā)生變化時(shí),我們需要更新UI。如果在子線程中直接更新UI,通常會(huì)拋出下面的異常:

11-07 13:33:04.393: ERROR/JavaBinder(1029):android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.

意思是,無(wú)法在子線程中更新UI。為此,我們需要通過(guò)Handler物件,通知主線程Ui Thread來(lái)更新界面。


網(wǎng)頁(yè)題目:android主線程,android主線程和子線程
當(dāng)前路徑:http://weahome.cn/article/dsdpcsh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部