Android進程間和線程間通信方式

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

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

??區(qū)別:

??(1)、一個程序至少有一個進程,一個進程至少有一個線程;

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

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

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

一、Android進程間通信方式

1.Bundle

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

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

2.ContentProvider

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

3.文件

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

4.Broadcast

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

5.AIDL方式

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

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

6.Messenger

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

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

7.Socket

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

二、Android線程間通信方式

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

1.AsyncTask機制

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

2.Handler機制

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

三、Android兩個子線程之間通信

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

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

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

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

new Thread(new Runnable() {

? ? ? ? ? ? public void run() {?

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

? ? ? ? ? ? ? ? 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,或者說是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();

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、簡歷準備 1、個人技能 (1)自定義控件、UI設(shè)計、常用動畫特效 自定義控件 ①為什么要自定義控件? Andr...
    lucas777閱讀 5,388評論 2 54
  • 1.要做一個盡可能流暢的ListView,你平時在工作中如何進行優(yōu)化的? ①Item布局,層級越少越好,使用hie...
    fozero閱讀 874評論 0 0
  • Android性能優(yōu)化(高級) 簡述Android的系統(tǒng)架構(gòu)?android的系統(tǒng)架構(gòu)從下往上分為Linux內(nèi)核層...
    梧桐樹biu閱讀 712評論 0 2
  • 序:很多都是自己的個人理解,不一定非常準確,供大家參考學(xué)習 大家應(yīng)該都用過進程間的通訊,那有沒有想過一個問題,進程...
    _水藍閱讀 1,006評論 0 3
  • 一、Git詳解 (1)安裝Git安裝完成之后,在開始菜單中找到 Git-->Git Bash,配置一下你的信息。 ...
    kjy_112233閱讀 3,279評論 0 6

友情鏈接更多精彩內(nèi)容