轉(zhuǎn)載請(qǐng)標(biāo)注:張小燕:http://www.cnblogs.com/zhangxinyan
1. Application 中的 service
我們知道Android中Service有三種類(lèi)型:Local Service,Local Bounded Service,Remote Service。
Local Service:基本是提供給自已應(yīng)用使用,通過(guò)startService(intent)來(lái)啟動(dòng)。
Local Bounded Service:也是提供給自己應(yīng)用使用,通過(guò)bindService(intent)啟動(dòng),然后在回調(diào)中獲得service,這種service一般很少寫(xiě),因?yàn)榧热恢惶峁┙o自己使用,又何必從回調(diào)繞個(gè)圈子呢。用第一種service就好了。
RemoteService:可以共享給更多使用者,這里就會(huì)涉及到IPC機(jī)制。在Android中,IPC機(jī)制是通過(guò)Binder來(lái)實(shí)現(xiàn)的。接下來(lái)就讓我們開(kāi)始看看Binder究竟是什么玩意吧~
2.Remote Service:
先來(lái)看看App層會(huì)遇到IPC的地方。
我們?cè)趯?xiě)App時(shí),當(dāng)遇到需要在后臺(tái)默默做點(diǎn)什么事情時(shí),就會(huì)采用Service這個(gè)組件,當(dāng)你這個(gè)Service要大公無(wú)私的向外面提供服務(wù)時(shí),我們會(huì)采用RemoteService這個(gè)玩意。下面我們就看一下怎么樣來(lái)寫(xiě)一個(gè)RemoteService:
1.先定義一個(gè)aidl文件:在這個(gè)文件里寫(xiě)上這個(gè)Service可以完成的功能接口
1 package com.example.remoteservice; 2 interface IRemoteService { 3 void doSomething ( );4 }
2.實(shí)現(xiàn)Remote Service:寫(xiě)一個(gè)Service組件,在這個(gè)組件里,實(shí)現(xiàn)Stub(Stub是啥?后面有說(shuō))的具體功能,這些功能就對(duì)應(yīng)了上面aidl文件里面定義的一些接口。
接著在回調(diào)函數(shù)onBind()中把這個(gè)實(shí)現(xiàn)的Stub對(duì)象返回出去。那誰(shuí)會(huì)來(lái)調(diào)用這個(gè)onBind()函數(shù)呢?當(dāng)然是ActivityManagerService啦,有關(guān)與ActivityManagerService的詳細(xì)內(nèi)容會(huì)新開(kāi)一篇詳細(xì)說(shuō)明。下面就看代碼吧:
1 public class RemoteService extends Service { 2 @Override 3 public IBinder onBind(Intent intent) { 4 if (IRemoteService.class.getName().equals(intent.getAction())) { 5 return mRemoteBinder; //把一個(gè)Binder對(duì)象返回出去。其實(shí)是返回到AMS里面了。AMS:ActivityManagerService。 6 } 7 return null; 8 } 9 private final IRemoteService.Stub mRemoteBinder =new IRemoteService.Stub() {//實(shí)現(xiàn)Stub對(duì)象要求的方法,即AIDL的實(shí)現(xiàn)。10 public void dosomething() {11 blablabla; 12 } 13 }; 14 }
3.訪問(wèn)Remote Service:接著就是在Activity里面啟動(dòng)和調(diào)用Service的功能了,怎么調(diào)用呢?看代碼:
1 public class Helloworld extends Activity 2 { 3 ... 4 @Override 5 public void onCreate(Bundle savedInstanceState) 6 { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.main); 9 bindService(new Intent(IRemoteService.class.getName()),mRemoteConnection, 10 Context.BIND_AUTO_CREATE); // 1.觸發(fā)Service端回調(diào)onBind()。 (1)11 ...12 mRemoteService.getPid(); //3. 會(huì)通過(guò)Binder IPC 將操作請(qǐng)求發(fā)送到Service端的Stub實(shí)現(xiàn)。 (3)13 ...14 } 15 16 private ServiceConnection mRemoteConnection = new ServiceConnection() {17 public void onServiceConnected(ComponentName className, IBinder service) { (2)18 Log.i("binder_test","IBinder service : " + service.getClass());//通過(guò)Log發(fā)現(xiàn),這個(gè)service是BinderProxy object,BinderProxy是什么呢?後面再說(shuō)。暫時(shí)按字面理解為Binder代理對(duì)象。19 20 21 mRemoteService = IRemoteService.Stub.asInterface(service); // 2.通過(guò)asInterface,把Binder代理對(duì)象轉(zhuǎn)化成接口。22 } 23 public void onServiceDisconnected(ComponentName className) { 24 mRemoteService = null; 25 } 26 }; 27 }
說(shuō)明:
(1) :在這里調(diào)用bindService,最后其實(shí)會(huì)調(diào)用到AMS(ActivityManagerService)中。AMS就會(huì)去查找當(dāng)前系統(tǒng)中有沒(méi)有已經(jīng)啟動(dòng)過(guò)這個(gè)Service了,如果沒(méi)有啟動(dòng)這個(gè)Service,就把它啟動(dòng)起來(lái)。然后會(huì)調(diào)用它的onBind()回調(diào),獲得Service的Binder對(duì)象。再經(jīng)過(guò)一系列處理后,從調(diào)用者 Activity 的 (2)這個(gè)地方回調(diào)回來(lái),把service傳給它,當(dāng)然其中對(duì)象會(huì)有一些變化,我們?cè)诨卣{(diào)的這個(gè)地方把返回的service打印了出來(lái):
所以那個(gè)回調(diào) onServiceConnected傳進(jìn)來(lái)的 IBinder service,它其實(shí)是一個(gè)BinderProxy!按照字面意思,我們稱(chēng)它為 Binder代理對(duì)象,先不管這個(gè)IBinder是來(lái)的,也不管BinderProxy到底是什么,先往下看,看下去你就會(huì)慢慢知道了。
這個(gè)對(duì)象返回到Activity中之后,通過(guò)asInterface進(jìn)行一個(gè)轉(zhuǎn)化,轉(zhuǎn)化成了接口,其實(shí)是轉(zhuǎn)化成了Proxy對(duì)象啦,Proxy對(duì)象實(shí)現(xiàn)了接口。
那這個(gè)轉(zhuǎn)化得來(lái)的mRemoteService,我們以后就稱(chēng)之為 Service代理對(duì)象。
(3) :這樣,獲得了Service的代理對(duì)象之后,就可以通過(guò)Service代理對(duì)象調(diào)用Service的功能啦。雖然Service具體的執(zhí)行是在另外一個(gè)進(jìn)程,但是你是感覺(jué)不到的。
3. AIDL 工具
上面說(shuō)的內(nèi)容似乎有點(diǎn)亂,那我們整理下上面的訪問(wèn)過(guò)程,可以看一下下面的圖:
這里面的Stub對(duì)象,Stub.Proxy對(duì)象,這些對(duì)象我們上面都沒(méi)有創(chuàng)建吧?這些類(lèi)其實(shí)都是由aidl工具自動(dòng)生成的。
Client中Activity,通過(guò)bindService,觸發(fā)Service回調(diào)onBind()方法,把一個(gè)Binder代理對(duì)象返回給Client。
Client通過(guò)轉(zhuǎn)化,轉(zhuǎn)化成一個(gè)Service代理對(duì)象,Client通過(guò)這個(gè)Service代理對(duì)象,在通過(guò)底層的Binder驅(qū)動(dòng),就可以調(diào)用進(jìn)Service進(jìn)程。在Service進(jìn)程收到請(qǐng)求后,會(huì)根據(jù)里面的一個(gè)參數(shù)值,找到對(duì)應(yīng)的函數(shù),執(zhí)行具體的操作。
下面這個(gè)類(lèi)就是用了aidl工具后,IRemoteService.aidl自動(dòng)生成的對(duì)應(yīng)的類(lèi):IRemoteService.java
1 package com.example.remoteservice; 2 3 public interface IRemoteService extends android.os.IInterface { 1 4 public static abstract class Stub extends android.os.Binder implements 5 com.example.remoteservice.IRemoteService {//繼承Binder,并且實(shí)現(xiàn)了IRemoteService接口 6 ... 7 public static com.example.remoteservice.IRemoteService asInterface(android.os.IBinder obj) {//根據(jù)傳進(jìn)來(lái)的IBinder對(duì)象創(chuàng)建一個(gè)Service 代理對(duì)象給客戶端。 8 ... 9 android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR); 10 if (((iin != null) && (iin instanceof com.example.remoteservice.IRemoteService))) { 11 return((com.example.remoteservice.IRemoteService) iin); 12 } 13 return new com.example.remoteservice.IRemoteService.Stub.Proxy(obj); //看,返回的是Proxy這個(gè)對(duì)象。就是Service代理對(duì)象。14 } 15 16 public android.os.IBinder asBinder() { 17 return this; 18 } 19 20 @Override 21 public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, 22 int flags)throwsandroid.os.RemoteException { //把IPC消息取出來(lái)解析,找到具體執(zhí)行方法。23 switch (code) { //根據(jù)code值,找到方法。24 case INTERFACE_TRANSACTION: { 25 } 26 case TRANSACTION_doSomething: { 27 } 28 } 29 return super.onTransact(code, data, reply, flags); 30 } 31 32 private static class Proxy implements com.example.remoteservice.IRemoteService {//實(shí)現(xiàn)了IRemoteService接口33 private android.os.IBinder mRemote; //實(shí)際上是BinderProxy對(duì)象34 ...35 public int doSomething() throws android.os.RemoteException {36 ...37 mRemote.transact(Stub.TRANSACTION_doSomething,_data, _reply, 0);//通過(guò)BinderProxy將命令發(fā)送出去。 38 ….39 } 40 static final int TRANSACTION_doSomething = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); //這玩意就是用來(lái)區(qū)別方法的code。41 } 42 43 public void doSomething() throwsandroid.os.RemoteException; 44 }
這里面呢,會(huì)涉及到幾個(gè)類(lèi),Proxy啦,Binder啦等等,他們的關(guān)系圖可以在下圖中看出:
那Stub和Proxy都實(shí)現(xiàn)了了IRemoteService。但是呢Proxy只是把參數(shù)包裝一下,通過(guò)mRemote發(fā)送出去。
Stub就是真正實(shí)現(xiàn)的地方了,不過(guò)這邊實(shí)現(xiàn)的代碼其實(shí)是寫(xiě)在Service里的,就是那個(gè)mRemoteBinder。
Proxy類(lèi)是Stub的一個(gè)子類(lèi)。Proxy里面的mRemote就是BinderProxy,通過(guò)它就可以把請(qǐng)求發(fā)送出去,然后再通過(guò)底層Binder的一些操作,最后走到Service進(jìn)程里去執(zhí)行一些操作。
那來(lái)總結(jié)一下吧,上面這個(gè)過(guò)程可以概括的說(shuō)是:
1.Activity通過(guò)AMS的bindService(String name),讓AMS做一些查找操作,然后AMS把一個(gè)service的Binder代理對(duì)象返回給Activity。
2.Activity通過(guò)一個(gè)轉(zhuǎn)換,創(chuàng)建一個(gè)service代理對(duì)象Proxy,其是在Proxy里面,還是利用Binder代理對(duì)象向service發(fā)送命令。
下一篇會(huì)將一下AMS里面的IPC機(jī)制:
聯(lián)系客服