国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Binder機(jī)制,從Java到C (1. IPC in Application Remote Service)

轉(zhuǎn)載請(qǐng)標(biāo)注:張小燕:http://www.cnblogs.com/zhangxinyan

1. Application 中的 service

我們知道Android中Service有三種類(lèi)型:Local ServiceLocal Bounded ServiceRemote 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ī)制:

Binder機(jī)制,從Java到C (2. IPC in System Service :AMS)

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
android筆記
使用AIDL(Android接口描述語(yǔ)言)設(shè)計(jì)和使用遠(yuǎn)程接口
【Android】Service
從 Remote Service Binding 學(xué)習(xí) AIDL 與 IPC
Android使用AIDL設(shè)計(jì)和調(diào)用遠(yuǎn)程接口
AIDL和Service的區(qū)別是什么
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服