生活随笔
收集整理的這篇文章主要介紹了
Android-深入理解AIDL
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近從新溫習AIDL,發現技術這玩意就跟女人一樣,你過久沒去了解就會對它陌生卻又充滿新鮮感,然后查看網上的多半是胡扯,粘貼,我這里整合下,里面如果有錯誤望大家及時指出。廢話不多說,進入主題
首先來了解幾點常識:
1,一個Android應用程序對應一個進程;
2,Android應用程序進程間需要借助IPC輕量級通訊協議;
3,切勿把線程和進程的概念搞混亂。一個進程可以包含多個線程,但是一個線程只會附屬于一個進程,可以理解成1對多的關系;
4,我們常見的Handler它是運行在UI主線程的,它負責的是異步處理數據,執行也是父線程和子線程;所以別把它和進程的概念混在一起。
進入主題,Android進程間的通訊:AIDL
這里我以為大家比較熟悉的C/S模式來講解整個通訊過程;但是我并沒有去新建立兩個項目了,就一個項目中,模擬進程通訊。不多說,先上項目圖
第一步,首先建立兩個aidl文件,forActivity.adil,forService.aidl 先來看看它們內部實現
[java] ?view plain
?copy package ?com.aidl;?? interface ?forActivity{?? ??void ?perAction();?? ??void ?showString( int ?count);?? }??
[java] ?view plain
?copy package ?com.aidl;?? import ?com.aidl.forActivity;?? interface ?forService{?? ?????void ?registerTestCall(forActivity?fa);?? ?????void ?callBack();?? }??
一看,哎喲,這里面的編碼規則和java文件一樣,但是這個時候,我其他地方要調用怎么辦?別著急編譯器會默認在gen文件中生成對應.java文件
打開其中一個文件查看下其中源碼,先不詳細分析,慢慢來,就好比追女生一樣,要慢慢來,急不得
[java] ?view plain
?copy ? ? ? ?? package ?com.example.androidaidl.aidl;?? public ? interface ?forActivity? extends ?android.os.IInterface?? {?? ?? public ? static ? abstract ? class ?Stub? extends ?android.os.Binder? implements ?com.example.androidaidl.aidl.forActivity?? {?? private ? static ? final ?java.lang.String?DESCRIPTOR?=? "com.example.androidaidl.aidl.forActivity" ;?? ?? public ?Stub()?? {?? this .attachInterface( this ,?DESCRIPTOR);?? }?? ? ? ? ?? public ? static ?com.example.androidaidl.aidl.forActivity?asInterface(android.os.IBinder?obj)?? {?? if ?((obj== null ))?{?? return ? null ;?? }?? android.os.IInterface?iin?=?obj.queryLocalInterface(DESCRIPTOR);?? if ?(((iin!= null )&&(iin? instanceof ?com.example.androidaidl.aidl.forActivity)))?{?? return ?((com.example.androidaidl.aidl.forActivity)iin);?? }?? return ? new ?com.example.androidaidl.aidl.forActivity.Stub.Proxy(obj);?? }?? @Override ? public ?android.os.IBinder?asBinder()?? {?? return ? this ;?? }?? @Override ? public ? boolean ?onTransact( int ?code,?android.os.Parcel?data,?android.os.Parcel?reply,? int ?flags)? throws ?android.os.RemoteException?? {?? switch ?(code)?? {?? case ?INTERFACE_TRANSACTION:?? {?? reply.writeString(DESCRIPTOR);?? return ? true ;?? }?? case ?TRANSACTION_performAction:?? {?? data.enforceInterface(DESCRIPTOR);?? this .performAction();?? reply.writeNoException();?? return ? true ;?? }?? }?? return ? super .onTransact(code,?data,?reply,?flags);?? }?? private ? static ? class ?Proxy? implements ?com.example.androidaidl.aidl.forActivity?? {?? private ?android.os.IBinder?mRemote;?? Proxy(android.os.IBinder?remote)?? {?? mRemote?=?remote;?? }?? @Override ? public ?android.os.IBinder?asBinder()?? {?? return ?mRemote;?? }?? public ?java.lang.String?getInterfaceDescriptor()?? {?? return ?DESCRIPTOR;?? }?? @Override ? public ? void ?performAction()? throws ?android.os.RemoteException?? {?? android.os.Parcel?_data?=?android.os.Parcel.obtain();?? android.os.Parcel?_reply?=?android.os.Parcel.obtain();?? try ?{?? _data.writeInterfaceToken(DESCRIPTOR);?? mRemote.transact(Stub.TRANSACTION_performAction,?_data,?_reply,?0 );?? _reply.readException();?? }?? finally ?{?? _reply.recycle();?? _data.recycle();?? }?? }?? }?? static ? final ? int ?TRANSACTION_performAction?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+? 0 );?? }?? public ? void ?performAction()? throws ?android.os.RemoteException;?? }??
第二步,新建mAIDLActivity.java文件,它模擬Client , 新建mAIDLService.java文件,它模擬Server;
? ? ? ? ? ?先看看mAIDLActivity.java文件;
[java] ?view plain
?copy public ? class ?mAIDLActivity? extends ?Activity?{?? ????private ? static ? final ?String?TAG?=? "AIDLActivity" ;?? ????private ?Button?btnOk;?? ????private ?Button?btnCancel;?? ????private ?Button?btnCallBack;?? ?? ????private ? void ?Log(String?str)?{?? ????????android.util.Log.d(TAG,?"------?" ?+?str?+? "------" );?? ????}?? ?????? ????@Override ?? ????protected ? void ?onCreate(Bundle?savedInstanceState)?{?? ?????????? ????????super .onCreate(savedInstanceState);?? ????????setContentView(R.layout.main);?? ????????btnOk?=?(Button)?findViewById(R.id.btn_ok);?? ????????btnCancel?=?(Button)?findViewById(R.id.btn_cancel);?? ????????btnCallBack?=?(Button)?findViewById(R.id.btn_callback);?? ????????btnOk.setOnClickListener(new ?OnClickListener()?{?? ????????????public ? void ?onClick(View?v)?{??
[java] ?view plain
?copy ???????????????????????? ?? ??????Intent?intent?=?new ?Intent(mAIDLActivity. this ,mAIDLService. class );?? ??????bindService(intent,?mcConnection,?Context.BIND_AUTO_CREATE);?? ???????? ????}?? });?? btnCancel.setOnClickListener(new ?OnClickListener()?{?? ????public ? void ?onClick(View?v)?{??
[java] ?view plain
?copy ???????????????????????????????? ?? ????????????????unbindService(mcConnection);?? ????????????????? ? ??????????}?? ????????});?? ????????btnCallBack.setOnClickListener(new ?OnClickListener()?{?? ?? ????????????@Override ?? ????????????public ? void ?onClick(View?v)?{?? ????????????????try ?{??
[java] ?view plain
?copy ??????????????????????????????????? ?? ????????????????mService.callBack();?? ????????????}?catch ?(RemoteException?e)?{?? ?????????????????? ????????????????e.printStackTrace();?? ????????????}?? ????????}?? ????});?? }?? ???forService?mService;?? ???forActivity?mActivity?=?new ?forActivity.Stub()?{?? ?????? ????@Override ?? ????public ? void ?perAction()? throws ?RemoteException?{?? ????????Log("執行了啦" );?? ????}?? ?? ????@Override ?? ????public ? void ?showString( int ?count)? throws ?RemoteException?{?? ????????Log(count+"" );?? ????}?? ?????? };?? ????? ???ServiceConnection?mcConnection?=?new ?ServiceConnection()?{?? ?????? ????@Override ?? ????public ? void ?onServiceDisconnected(ComponentName?name)?{?? ?????????? ????}?? ?????? ????@Override ?? ????public ? void ?onServiceConnected(ComponentName?name,?IBinder?service)?{?? ????????mService?=?forService.Stub.asInterface(service);?? ????????try ?{?? ????????????mService.registerTestCall(mActivity);?? ????????}?catch ?(RemoteException?e)?{?? ?? ????????}?? ????}?? };??
這三個按鈕的作用我就不用說了吧,那么明白的解釋在那里還不懂的話,那你就別繼續看了,好好看看片,擼一管撤退吧。
先分析下上述文件
[java] ?view plain
?copy ServiceConnection?mcConnection?=? new ?ServiceConnection()?{?? ?????????? ????????@Override ?? ????????public ? void ?onServiceDisconnected(ComponentName?name)?{?? ?????????????? ????????}?? ?????????? ????????@Override ?? ????????public ? void ?onServiceConnected(ComponentName?name,?IBinder?service)?{?? ????????????mService?=?forService.Stub.asInterface(service);?? ????????????try ?{?? ????????????????mService.registerTestCall(mActivity);?? ????????????}?catch ?(RemoteException?e)?{?? ?? ????????????}?? ????????}?? ????};??
ServiceConnection的使用和介紹我上一篇博文已經說了,大家可以去看看,說實在的就是如果不是研究AIDL,這家伙我估計都不會看到.
看這句代碼
[java] ?view plain
?copy mService?=?forService.Stub.asInterface(service);??
如果直接看的話不看源碼,我第一想到的就是實例化?強轉,?一大堆不靠譜的邏輯,作為一個裝逼程序猿,如果遇到不知道的情況,別瞎猜,看源碼才是王道.來打開forService.文件
[java] ?view plain
?copy public ? interface ?forService? extends ?android.os.IInterface?? {?? ?? public ? static ? abstract ? class ?Stub? extends ?android.os.Binder? implements ?com.aidl.forService?? {?? private ? static ? final ?java.lang.String?DESCRIPTOR?=? "com.aidl.forService" ;?? ?? public ?Stub()?? {?? this .attachInterface( this ,?DESCRIPTOR);?? }?? ? ? ? ?? public ? static ?com.aidl.forService?asInterface(android.os.IBinder?obj)?? {?? if ?((obj== null ))?{?? return ? null ;?? }?? android.os.IInterface?iin?=?obj.queryLocalInterface(DESCRIPTOR);?? if ?(((iin!= null )&&(iin? instanceof ?com.aidl.forService)))?{?? return ?((com.aidl.forService)iin);?? }?? return ? new ?com.aidl.forService.Stub.Proxy(obj);?? }??
這里我們發現,Stub是forService的內部靜態抽象類,并且是繼承Binder和實例化了接口forService. 查看方法adInterface中的實現,它分三步來判斷
?1,如果是空,直接給你空,讓你一邊玩去
? 2,如果傳入的Ibinder對象就是com.aidl.forService,因為forService的繼承的IInterface,看IInterface的介紹Base class for Binder interfaces. When defining a new interface, you must derive it from IInterface.那得列直接強轉成forService對象返回去, 萬事大吉; ? 3.如果為空,那就new一個新的,對象嘛.程序猿從來不缺.
下面繼續分析mAIDLService文件.不多說,先看源碼
[java] ?view plain
?copy public ? class ?mAIDLService? extends ?Service?{?? ??????? ????@Override ?? ????public ?IBinder?onBind(Intent?intent)?{?? ????????return ?mIBinder;?? ????}?? ????forActivity?mActivity;?? ????int ?count= 0 ;?? ????forService.Stub?mIBinder??=?new ?forService.Stub()?{?? ?????????? ????????@Override ?? ????????public ? void ?registerTestCall(forActivity?fa)? throws ?RemoteException?{?? ????????????mActivity?=?fa;?? ????????}?? ?????????? ????????@Override ?? ????????public ? void ?callBack()? throws ?RemoteException?{?? ????????????mActivity.perAction();?? ????????????mActivity.showString(++count);?? ????????}?? ????};?? }??
它這里相對就簡單了,基本不用多說了吧,這里要注意的就是
[java] ?view plain
?copy public ?IBinder?onBind(Intent?intent)?{?? ????????return ?mIBinder;?? ????}??
它返回的是當前new出來的forService對象.也就是我們前面ServiceConnection回調拿到的IBinder,
那這里就慢慢明朗了,整個相互間的通訊也就清楚了,當按下btnCallBack按鈕的時候,首先會調用forService中的callBack方法,而callBack方法的實現中又調用了forActivity的perAction.通過forActivity和forService的這次握手,就達到了mAIDLActivity和mAIDLService一直及時通訊
說到這里有朋友跟我說ContentProvider就可以直接實現兩個應用間的數據傳遞了啊,為什么還要用AIDL,我轉頭一聲呵呵,我列出下面幾個區分點估計大家就明白了
1.ContentProvider是單向性的,不及時的,而AIDL是雙向性,及時的。就這么來說吧。ContentProvider就好比你看到一個漂亮的妹子,你一直看著她,但是她卻對你無視,你看不清楚她身體的變化;AIDL就是你看到那個漂亮的妹子,她也看著,你下面的異樣,立即反饋給了她,而你也看到了她嘴邊的異樣,這比喻好理解嗎?哈哈哈
?好了中間有些地方如果有錯或者大家要補充的直接留言吧,然后懇請轉載的指明地址,不然又是一堆廢文到處跑。
下篇博文準備分析下IBinder和Binder!
參考網友論文
http://blog.csdn.net/saintswordsman/article/details/5130947
源碼下載
http://download.csdn.net/detail/eran12101030/7993485
原文地址:http://blog.csdn.net/eran12101030/article/details/39672189
總結
以上是生活随笔 為你收集整理的Android-深入理解AIDL 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。