跨進(jìn)程間如何進(jìn)行AIDL IPC 通信(一)

AIDL是Android跨進(jìn)程間的一種非常重要的IPC通信機(jī)制,今天我們將來詳細(xì)講述如何不同app之間如何進(jìn)行AIDL IPC通信。

1. 創(chuàng)建service端工程

由于Android Studio剛剛發(fā)布3.0版本,所以我們就用它來嘗個鮮。
可用原來android studio 版本點(diǎn)擊菜單Help-->Check for Updates... 之后Android studio就會自動下載更新包進(jìn)行升級,可惜我升級半天,升級期間報幾個沖突,結(jié)果升級失敗,自動回滾,導(dǎo)致原來的AS2.3.3無法啟動,無奈只能直接下載AS3.0手動安裝。

a) 創(chuàng)建AIDL Service端工程AidlServerDemo

創(chuàng)建完后工程項(xiàng)目結(jié)構(gòu)如圖1所示:


圖1

b) 創(chuàng)建AIDL文件

右擊Java目錄 New --> AIDL --> AIDL File
輸入接口名稱IOnroad
此時會在與java同一目錄下生成aidl文件夾及對應(yīng)的包名和aidl文件
如圖2所示:


圖2

AS自動幫我們生成了一個基本類型的aidl接口

void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

但我們并不打算用它,我們自己來定義一個簡單的基本類型

String sayHello(String name, int age);

點(diǎn)擊菜單Build-->Make Project,即可在對應(yīng)目錄下生成Java接口文件,如圖3所示:

圖3

c) 創(chuàng)建一個service來實(shí)現(xiàn)這個接口類

public class OnroadService extends Service {
    public OnroadService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

我們創(chuàng)建了一個OnroadService, AS自動幫我們生成了一個構(gòu)造函數(shù)及實(shí)現(xiàn)了onBind接口,由于該接口未綁定相應(yīng)的binder,所以暫時返回UnsupportedOperationException("Not yet implemented")異常。

接下來我們將在這個service里實(shí)現(xiàn)我們的aidl接口, 并在onBind方法里返回mBinder給調(diào)用者,調(diào)用者就可以透過mBinder調(diào)用我們的aidl接口了。

private IOnroad.Stub mBinder = new IOnroad.Stub() {
        @Override
        public String sayHello(String name, int age) throws RemoteException {
            String str = "Hello " + name + ", your age is " + age;
            Log.d(TAG, str);
            return str;
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mBinder;
    }

d) 在AndroidManifest.xml注冊該service

<service
       android:name=".service.OnroadService"
       android:enabled="true"
       android:exported="true">
       <intent-filter>
             <action android:name="tech.onroad.aidlservicedemo.onroadservice"/>
             <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>
</service>

至此,整個service端已創(chuàng)建完成。

2. 創(chuàng)建Client端工程

a) 創(chuàng)建AIDL Client端工程AidlClientDemo

b) 復(fù)制service端的aidl文件及aidl對應(yīng)的java文件到客戶端

為了能在Client端掉用service端的接口,必須將service端的aidl文件及AS自動生成的aidl對應(yīng)的java文件復(fù)制到該工程,且保持包名不變。如圖4所示:


圖4

c) 創(chuàng)建ServiceConnection類

用于綁定Service, 若綁定成功,會回調(diào)onServiceConnected()方法,我們可以復(fù)寫該方法,獲取該service的ibinder接口; 若Service斷開連接,則必須銷毀binder實(shí)例,否則會造成內(nèi)存泄漏。

ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mIOnroad = IOnroad.Stub.asInterface(iBinder);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mIOnroad = null;
        }
    };

d) 綁定服務(wù)

為了方便,我們讓Activity啟動的時候就去綁定服務(wù)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent mServiceIntent = new Intent();
        mServiceIntent.setAction("tech.onroad.aidlservicedemo.onroadservice");
        mServiceIntent.setPackage("tech.onroad.aidlserverdemo");
        bindService(mServiceIntent, conn, Context.BIND_AUTO_CREATE);
    }

setAction里的參數(shù)tech.onroad.aidlserverdemo就是我們Service在AndroidManifest.xml注冊的action, setPackage需指定service所在的包名,因?yàn)樵贏ndroid 5.0以后,android已不再支持隱式Intent Service,所以必須指定service所在的包名。這樣Client端綁定Service就已經(jīng)完成。

e) 調(diào)用aidl接口

接下來我們嘗試調(diào)用一下service端的aidl接口,看能否調(diào)用成功。

public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mIOnroad = IOnroad.Stub.asInterface(iBinder);
            try {
                String svcRet = mIOnroad.sayHello("dflw", 20);
                Log.d("Client", "Service return " + svcRet);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

為了圖方便,我直接綁定成功后的回調(diào)接口onServiceConnected()調(diào)用service的AIDL接口。

3. 測試

將AidlServerDemo及AidlClientDemo的apk裝載到Android設(shè)備或者模擬器上,

11-09 05:52:24.622 5439-5452/tech.onroad.aidlserverdemo D/OnroadService: Hello Liting, your age is 20

11-09 05:52:24.622 6662-6662/tech.onroad.aidlclientdemo D/Client: Service return Hello Liting, your age is 20

由上面的log可知,Client端已能正確調(diào)用Service端的接口,并成功將參數(shù)傳遞給Service端,且Service端也能將結(jié)果正確返回給Client.

完整代碼可到我的github下載:
https://github.com/onroadtech/AidlDemo


更多博文可訪問我的個人網(wǎng)站:www.onroad.tech
歡迎指定,共同進(jìn)步,指定郵箱:onroad_tech@163.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,057評論 25 709
  • Android跨進(jìn)程通信IPC整體內(nèi)容如下 1、Android跨進(jìn)程通信IPC之1——Linux基礎(chǔ)2、Andro...
    隔壁老李頭閱讀 10,971評論 13 43
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • Jianwei's blog 首頁 分類 關(guān)于 歸檔 標(biāo)簽 巧用Android多進(jìn)程,微信,微博等主流App都在用...
    justCode_閱讀 6,118評論 1 23
  • 新學(xué)期開學(xué),想淺談一下關(guān)于你的類型和舍友的類型對你的影響是什么?也借此希望對即將進(jìn)入大學(xué)住宿生活的學(xué)弟妹提供一些參...
    先秦啊閱讀 778評論 3 4

友情鏈接更多精彩內(nèi)容