跨進(jìn)程通信AIDL的使用

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


前期基礎(chǔ)知識儲備

  • IPC定義:

IPC是intent-Process Communication的縮寫,含義為進(jìn)程間通信或者跨進(jìn)程通信,是指兩個進(jìn)程之間進(jìn)行數(shù)據(jù)交換的過程。IPC不是Android所獨(dú)有的,任何一個操作系統(tǒng)都需要有相應(yīng)的IPC機(jī)制,比如Windows上可以通過剪貼板、管道和郵槽等來進(jìn)行進(jìn)程間通信,而Linux上可以通過命名共享內(nèi)容、信號量等來進(jìn)行線程間通信。對于Android來說,它也有自己的進(jìn)程間通信方式,Android建構(gòu)在Linux基礎(chǔ)上,繼承了一部分Linux的通信方式,同時Android也有自己特有的通信方式。


創(chuàng)建應(yīng)用工程

image.png
  • 創(chuàng)建AIDL Service端工程modelAPP

  • 創(chuàng)建AIDL文件

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

image.png

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

interface IMyAidlInterface{
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

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

interface IOnroad {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
//    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
//            double aDouble, String aString);


    void sayHello(String name,int age);
}

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


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

我們創(chuàng)建了一個OnroadService, 并在onBind方法里返回mBinder給調(diào)用者,調(diào)用者就可以透過mBinder調(diào)用我們的aidl接口了。

public class OnroadService extends Service {
    public OnroadService() {
    }
    private String TAG = "OnroadService";
    private IOnroad.Stub binder = new IOnroad.Stub() {

        @Override
        public void sayHello(String name, int age) throws RemoteException {
            String text = "sayHello: --->name" + name + "age:" + age;
            Log.i(TAG, text);
            //Toast.makeText(OnroadService.this, text, Toast.LENGTH_SHORT).show();
        }
    };
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
}

  • 在AndroidManifest.xml注冊該service

<service
    android:name=".service.OnroadService"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.lypeer.aidl" />

        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

創(chuàng)建Client端應(yīng)用

  • 創(chuàng)建AIDL Client端工程工程model

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

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


image.png
  • 創(chuàng)建ServiceConnection類

    用于綁定Service, 若綁定成功,會回調(diào)onServiceConnected()方法,我們可以復(fù)寫該方法,獲取該service的ibinder接口; 若Service斷開連接,則必須銷毀binder實(shí)例,否則會造成內(nèi)存泄漏。
private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
       // IOnroad.Stub binder =
        IOnroad onroad = IOnroad.Stub.asInterface(service);
        try {
//                onroad.sayHello();
            onroad.sayHello("哈嘍",100);
        } catch (RemoteException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "有異常的情況!", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        
    }
};
  • 綁定服務(wù)

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

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Intent intent = new Intent();
    intent.setAction("com.lypeer.aidl");
    intent.setPackage("com.zxn.service");
    bindService(intent,connection,BIND_AUTO_CREATE);
}

  • 調(diào)用aidl接口

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

測試

可以看到服務(wù)端從異步線程傳遞過來的數(shù)據(jù),日志輸出如下

--->name:say onClickage:1028Thread:Binder:5786_4

Day08_Service_Demo

最后編輯于
?著作權(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)容

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