日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android-深入理解AIDL

發布時間:2025/3/15 Android 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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
  • /*?
  • ?*?This?file?is?auto-generated.??DO?NOT?MODIFY.?
  • ?*?Original?file:?F:\\workspace\\AndroidAIDL\\src\\com\\example\\androidaidl\\aidl\\forActivity.aidl?
  • ?*/??
  • package?com.example.androidaidl.aidl;??
  • public?interface?forActivity?extends?android.os.IInterface??
  • {??
  • /**?Local-side?IPC?implementation?stub?class.?*/??
  • 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";??
  • /**?Construct?the?stub?at?attach?it?to?the?interface.?*/??
  • public?Stub()??
  • {??
  • this.attachInterface(this,?DESCRIPTOR);??
  • }??
  • /**?
  • ?*?Cast?an?IBinder?object?into?an?com.example.androidaidl.aidl.forActivity?interface,?
  • ?*?generating?a?proxy?if?needed.?
  • ?*/??
  • 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)?{??
  • ????????//?TODO?Auto-generated?method?stub??
  • ????????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);??
  • ??????//startService(intent);??
  • ????}??
  • });??
  • btnCancel.setOnClickListener(new?OnClickListener()?{??
  • ????public?void?onClick(View?v)?{??
  • [java]?view plain?copy
  • ????????????????????????????????//取消綁定??
  • ????????????????unbindService(mcConnection);??
  • ????????????????/*unbindService(mConnection);?
  • ????????????????//?stopService(intent);?
  • */??????????}??
  • ????????});??
  • ????????btnCallBack.setOnClickListener(new?OnClickListener()?{??
  • ??
  • ????????????@Override??
  • ????????????public?void?onClick(View?v)?{??
  • ????????????????try?{??
  • [java]?view plain?copy
  • ???????????????????????????????????//進程數據交互通訊??
  • ????????????????mService.callBack();??
  • ????????????}?catch?(RemoteException?e)?{??
  • ????????????????//?TODO?Auto-generated?catch?block??
  • ????????????????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??
  • {??
  • /**?Local-side?IPC?implementation?stub?class.?*/??
  • public?static?abstract?class?Stub?extends?android.os.Binder?implements?com.aidl.forService??
  • {??
  • private?static?final?java.lang.String?DESCRIPTOR?=?"com.aidl.forService";??
  • /**?Construct?the?stub?at?attach?it?to?the?interface.?*/??
  • public?Stub()??
  • {??
  • this.attachInterface(this,?DESCRIPTOR);??
  • }??
  • /**?
  • ?*?Cast?an?IBinder?object?into?an?com.aidl.forService?interface,?
  • ?*?generating?a?proxy?if?needed.?
  • ?*/??
  • 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的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。