古詩詞大全網 - 成語大全 - android線程間通信有哪些方式

android線程間通信有哪些方式

進程:是具有壹定獨立功能的程序關於某個數據集合上的壹次運行活動,進程是系統進行資源分配和調度的壹個獨立單位。

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

區別:

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

(2)、線程的劃分尺度小於進程,使得多線程程序的並發性高;

(3)、進程在執行過程中擁有獨立的內存單元,而多個線程***享內存,但線程之間沒有單獨的地址空間,壹個線程死掉就等於整個進程死掉。

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

壹、Android進程間通信方式

1.Bundle

由於Activity,Service,Receiver都是可以通過Intent來攜帶Bundle傳輸數據的,所以我們可以在壹個進程中通過Intent將攜帶數據的Bundle發送到另壹個進程的組件。

缺點:無法傳輸Bundle不支持的數據類型。

2.ContentProvider

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

3.文件

兩個進程可以到同壹個文件去交換數據,我們不僅可以保存文本文件,還可以將對象持久化到文件,從另壹個文件恢復。要註意的是,當並發讀/寫時可能會出現並發的問題。

4.Broadcast

Broadcast可以向android系統中所有應用程序發送廣播,而需要跨進程通訊的應用程序可以監聽這些廣播。

5.AIDL方式

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

AIDL通過定義服務端暴露的接口,以提供給客戶端來調用,AIDL使服務器可以並行處理,而Messenger封裝了AIDL之後只能串行運行,所以Messenger壹般用作消息傳遞。

6.Messenger

Messenger是基於AIDL實現的,服務端(被動方)提供壹個Service來處理客戶端(主動方)連接,維護壹個Handler來創建Messenger,在onBind時返回Messenger的binder。

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

7.Socket

Socket方法是通過網絡來進行數據交換,註意的是要在子線程請求,不然會堵塞主線程。客戶端和服務端建立連接之後即可不斷傳輸數據,比較適合實時的數據傳輸

二、Android線程間通信方式

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

1.AsyncTask機制

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

2.Handler機制

Handler,繼承自Object類,用來發送和處理Message對象或Runnable對象;Handler在創建時會與當前所在的線程的Looper對象相關聯(如果當前線程的Looper為空或不存在,則會拋出異常,此時需要在線程中主動調用Looper.prepare()來創建壹個Looper對象)。使用Handler的主要作用就是在後面的過程中發送和處理Message對象和讓其他的線程完成某壹個動作(如在工作線程中通過Handler對象發送壹個Message對象,讓UI線程進行UI的更新,然後UI線程就會在MessageQueue中得到這個Message對象(取出Message對象是由其相關聯的Looper對象完成的),並作出相應的響應)。

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

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

主線程和子線程之間的通信可以通過主線程中的handler把子線程中的message發給主線程中的looper,或者,主線程中的handler通過post向looper中發送壹個runnable。但looper默認存在於main線程中,子線程中沒有Looper,該怎麽辦呢?其實原理很簡單,把looper綁定到子線程中,並且創建壹個handler。在另壹個線程中通過這個handler發送消息,就可以實現子線程之間的通信了。

子線程創建handler的兩種方式:

方式壹:給子線程創建Looper對象:

new Thread(new Runnable() {

public void run() {

Looper.prepare(); // 給這個Thread創建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()){ // 區別在這!!!

@Override

public void handleMessage(Message msg) {

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

}

};

handler.sendEmptyMessage(1);

};

}).start();