【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android中怎么實(shí)現(xiàn)進(jìn)程間通信_(tái)第1頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android中怎么實(shí)現(xiàn)進(jìn)程間通信_(tái)第2頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android中怎么實(shí)現(xiàn)進(jìn)程間通信_(tái)第3頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android中怎么實(shí)現(xiàn)進(jìn)程間通信_(tái)第4頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android中怎么實(shí)現(xiàn)進(jìn)程間通信_(tái)第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余2頁(yè)可下載查看

付費(fèi)下載

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android中怎么實(shí)現(xiàn)進(jìn)程間通信

這篇文章給大家介紹Android中怎么實(shí)現(xiàn)進(jìn)程間通信,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。進(jìn)程間通信(ipc)IPC方法總是產(chǎn)生客戶/服務(wù)端模式的調(diào)用,也即是客戶端組件(Activity/Service)持有服務(wù)端Service的組件,只能是客戶端主動(dòng)調(diào)用服務(wù)端的方法,服務(wù)端無(wú)法反過(guò)來(lái)調(diào)用客戶端的方法,因?yàn)镮PC的另一端Service無(wú)法獲取客戶端的對(duì)象。binderBinder是一種進(jìn)程間通信機(jī)制。安卓中跨進(jìn)程通訊就是通過(guò)binder。當(dāng)綁定服務(wù)的時(shí)候會(huì)返回一個(gè)binder對(duì)象,然后通過(guò)他進(jìn)行多進(jìn)程間的通信。Binder只需要一次數(shù)據(jù)拷貝,性能上僅次于共享內(nèi)存。在Android系統(tǒng)中,這個(gè)運(yùn)行在內(nèi)核空間,負(fù)責(zé)各個(gè)用戶進(jìn)程通過(guò)Binder實(shí)現(xiàn)通信的內(nèi)核模塊就叫Binder驅(qū)動(dòng)(BinderDirver)。BinderIPC機(jī)制中涉及到的內(nèi)存映射通過(guò)mmap()來(lái)實(shí)現(xiàn),mmap()是操作系統(tǒng)中一種內(nèi)存映射的方法。內(nèi)存映射簡(jiǎn)單的講就是將用戶空間的一塊內(nèi)存區(qū)域映射到內(nèi)核空間。映射關(guān)系建立后,用戶對(duì)這塊內(nèi)存區(qū)域的修改可以直接反應(yīng)到內(nèi)核空間;反之內(nèi)核空間對(duì)這段區(qū)域的修改也能直接反應(yīng)到用戶空間。內(nèi)存映射能減少數(shù)據(jù)拷貝次數(shù),實(shí)現(xiàn)用戶空間和內(nèi)核空間的高效互動(dòng)。兩個(gè)空間各自的修改能直接反映在映射的內(nèi)存區(qū)域,從而被對(duì)方空間及時(shí)感知。也正因?yàn)槿绱耍瑑?nèi)存映射能夠提供對(duì)進(jìn)程間通信的支持。BinderIPC正是基于內(nèi)存映射(mmap)來(lái)實(shí)現(xiàn)的Binder通信中的代理模式我們已經(jīng)解釋清楚Client、Server借助Binder驅(qū)動(dòng)完成跨進(jìn)程通信的實(shí)現(xiàn)機(jī)制了,但是還有個(gè)問(wèn)題會(huì)讓我們困惑。A進(jìn)程想要B進(jìn)程中某個(gè)對(duì)象(object)是如何實(shí)現(xiàn)的呢?畢竟它們分屬不同的進(jìn)程,A進(jìn)程沒法直接使用B進(jìn)程中的object。前面我們介紹過(guò)跨進(jìn)程通信的過(guò)程都有Binder驅(qū)動(dòng)的參與,因此在數(shù)據(jù)流經(jīng)Binder驅(qū)動(dòng)的時(shí)候驅(qū)動(dòng)會(huì)對(duì)數(shù)據(jù)做一層轉(zhuǎn)換。當(dāng)A進(jìn)程想要獲取B進(jìn)程中的object時(shí),驅(qū)動(dòng)并不會(huì)真的把object返回給A,而是返回了一個(gè)跟object看起來(lái)一模一樣的代理對(duì)象objectProxy,這個(gè)objectProxy具有和object一摸一樣的方法,但是這些方法并沒有B進(jìn)程中object對(duì)象那些方法的能力,這些方法只需要把把請(qǐng)求參數(shù)交給驅(qū)動(dòng)即可。對(duì)于A進(jìn)程來(lái)說(shuō)和直接調(diào)用object中的方法是一樣的。當(dāng)Binder驅(qū)動(dòng)接收到A進(jìn)程的消息后,發(fā)現(xiàn)這是個(gè)objectProxy就去查詢自己維護(hù)的表單,一查發(fā)現(xiàn)這是B進(jìn)程object的代理對(duì)象。于是就會(huì)去通知B進(jìn)程調(diào)用object的方法,并要求B進(jìn)程把返回結(jié)果發(fā)給自己。當(dāng)驅(qū)動(dòng)拿到B進(jìn)程的返回結(jié)果后就會(huì)轉(zhuǎn)發(fā)給A進(jìn)程,一次通信就完成了其實(shí)進(jìn)程間通信就是為了實(shí)現(xiàn)數(shù)據(jù)共享。一個(gè)程序不同組件在不同進(jìn)程也叫多進(jìn)程,和倆個(gè)應(yīng)用沒有本質(zhì)區(qū)別。使用process屬性可以實(shí)現(xiàn)多進(jìn)程,但是會(huì)帶來(lái)很多麻煩,主要原因是共享數(shù)據(jù)會(huì)失敗,弊端有:靜態(tài)和單利失效,同步失效,sharedprefer也變的不可靠等問(wèn)題。多進(jìn)程通信的方式1.使用intent的附加信息extras來(lái)傳遞,通過(guò)bundle,傳遞的是bundle支持的類型,比如基本數(shù)據(jù)類型、實(shí)現(xiàn)pracellable或serializeable的對(duì)象/**指定包名和帶包名的Activity的名字*/

ComponentName

componentName

=

new

ComponentName("com.example.androidaidl",

"com.example.androidaidl.MainActivity");

Intent

intent

=

new

Intent();

intent.putExtra("id",

1001);

intent.setComponent(componentName);

startActivity(intent);2.使用文件共享,序列化或是sharedpre,不過(guò)不適用于讀寫并發(fā)的操作3.廣播:Android的廣播是系統(tǒng)級(jí)的,只要傳遞的Action一樣,就可以接收到其他進(jìn)程廣播的消息,廣播中可以通過(guò)Intent傳遞數(shù)據(jù)。4.scheme協(xié)議是android中的一種頁(yè)面內(nèi)跳轉(zhuǎn)協(xié)議,通過(guò)定義自己的scheme協(xié)議,可以非常方便跳轉(zhuǎn)app中的各個(gè)頁(yè)面,并且傳遞數(shù)據(jù),還是可以通過(guò)H5頁(yè)面跳轉(zhuǎn)指定頁(yè)面等。5.ContentProvider(進(jìn)程間數(shù)據(jù)共享)和message一樣,底層也是binder,除了oncreate方法其他方法(crud)都是運(yùn)行在bindler線程里。所以在oncerate里不能做耗時(shí)操作。Android本身就提供了不少的ContentProvider訪問(wèn),比如聯(lián)系人、相冊(cè)等。訪問(wèn)ContentProvider,需要通過(guò)Uri,需要以“content://”開頭。在其他應(yīng)用訪問(wèn)通過(guò)uri(主機(jī)名):ContentResolver

resolver

=

getActivity().getContentResolver();

/**com.mh.getdata/stock這個(gè)要和Provider所在進(jìn)程中添加的Uri一致*/

Uri

uri

=

Uri.parse("content://com.mh.getdata/stock");

Cursor

cursor

=

resolver.query(uri,

null,

null,

null,

null);常規(guī)通訊只有允許不同應(yīng)用的客戶端用IPC方式訪問(wèn)服務(wù),并且想要在服務(wù)中處理多線程(多任務(wù))時(shí),才有必要使用AIDL。如果您不需要執(zhí)行跨越不同應(yīng)用的并發(fā)IPC,就應(yīng)該通過(guò)實(shí)現(xiàn)一個(gè)Binder創(chuàng)建接口;或者,如果您想執(zhí)行IPC,但根本不需要處理多線程,則使用Messenger類來(lái)實(shí)現(xiàn)接口。無(wú)論如何,在實(shí)現(xiàn)AIDL之前,請(qǐng)您務(wù)必理解綁定服務(wù)。aidl文檔1.通過(guò)Messenger進(jìn)行傳遞(handler),在遠(yuǎn)程服務(wù)里創(chuàng)建handler(接收客戶端發(fā)送的消息)、Messenger對(duì)像,在onbind里返回(Messenger.getbinder)。在客戶端綁定服務(wù),拿著Messenger對(duì)象發(fā)消息(可以用bundle)。在遠(yuǎn)程服務(wù)的handlermessage方法就會(huì)收到。他是一個(gè)個(gè)處理的,如果大量并發(fā)請(qǐng)求用aidl,Messenger底層就是aidl在客戶端中創(chuàng)建一個(gè)Messenger。然后,當(dāng)客戶端收到onServiceConnected()回調(diào)時(shí),會(huì)向服務(wù)發(fā)送一條Message,并在其send()方法的replyTo參數(shù)中包含客戶端的Messenger。注意:Messenger和Message是倆個(gè)東西

public

void

sayHello(View

v)

{

if

(!mBound)

return;

Message

msg

=

Message.obtain(null,

MessengerService.MSG_SAY_HELLO,

0,

0);

try

{

mService.send(msg);

}

catch

(RemoteException

e)

{

e.printStackTrace();

}

}2.直接使用Binder對(duì)象:缺點(diǎn)是這種方式不能進(jìn)行跨進(jìn)程,跨應(yīng)用程序的函數(shù)調(diào)用。只能實(shí)現(xiàn)在同一個(gè)進(jìn)程之中,同一個(gè)應(yīng)用程序之中的不同的組件之間通訊。用法:繼承Binder,然后在service里return繼承Binder用它的對(duì)象返回,客戶端將bind對(duì)象強(qiáng)轉(zhuǎn)成自定義BindAIDLAndroidinterfacedefinitionlanguage(android接口定義語(yǔ)言),用來(lái)跨進(jìn)程的訪問(wèn)方法。aidl操作步驟:1.在兩個(gè)項(xiàng)目中新建普通文件(new->General->File),后綴名改成(aidl),客戶端和服務(wù)端中這個(gè)文件所在的包名要保持一致,內(nèi)容也要一樣編譯之后,會(huì)在gen目錄下,自動(dòng)產(chǎn)生同名的,后綴為Java的文件。里面有我們要用到的Stub類。public

static

abstract

class

Stub

extends

android.os.Binder

implements

com.example.aidl.AidlFunctions2.在接口文件AIDLFunctions.aidl中,我們定義一個(gè)方法showinterface

AidlFunctions{

void

show();

}3.AIDL的使用,需要一個(gè)Service配合,所以我們?cè)诜?wù)端還要聲明一個(gè)Servicepublic

class

AIDLService

extends

Service

{

//stub就是系統(tǒng)自動(dòng)產(chǎn)生的

AidlFunctions.Stub

binder;

@Override

public

void

onCreate()

{

//

TODO

Auto-generated

method

stub

super.onCreate();

}

@Override

public

IBinder

onBind(Intent

intent)

{

//

TODO

Auto-generated

method

stub

binder

=

new

AidlFunctions.Stub()

{

@Override

//這里是我們?cè)诮涌谥新暶鞯姆椒ǖ膶?shí)現(xiàn)

public

void

show()

throws

RemoteException

{

//

TODO

Auto-generated

method

stub

System.out.println("收到");

}

};

return

binder;

}

}4.客戶端://綁定服務(wù),要用到ServiceConnection

private

ServiceConnection

serviceConnection;

//自定義的接口,和服務(wù)端一樣

private

AidlFunctions

aidlFunctions;

serviceConnection

=

new

ServiceConnection()

{

@Override

public

void

onServiceDisconnected(ComponentName

name)

{

System.out.println("ServiceDisconnected");

}

@Override

public

void

onServiceConnected(ComponentName

name,

IBinder

service)

{

System.out.println("ServiceConnected");

aidlFunctions

=

AidlFunctions.Stub.asInterface(service);

}

};

Intent

intent

=

new

Intent("com.example.androidaidl.AIDLService");

bindService(intent,

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論