跨進程間如何進行AIDL IPC 通信(四)

在前三篇博客中,我們介紹了如何進行AIDL IPC通信,代碼設計及AIDL數(shù)據(jù)傳輸?shù)念愋汀T诘谝黄┛痛a設計中,我們曾說過,需要將AIDL接口文件及對應生成的Java文件要原封不動拷貝到客戶端,這樣客戶端才能正常編譯執(zhí)行,但是這樣操作非常麻煩且不合理,所以今天我們將要介紹如何將AIDL接口文件及對應生成的Java文件生成Jar包庫,直接丟給第三方客戶端使用。嚴格意義上說,這篇博客不屬于AIDL IPC通信的范疇,但為了使整個AIDL IPC通信設計的連續(xù)性,我還是決定將其放到這里。同樣以前面的工程為例:

1. 創(chuàng)建Module

創(chuàng)建Module其實就是為了創(chuàng)建android lib庫。由于我們的AIDL接口是在service端設計的,且由service端對外提供,因此我們選擇在service端工程創(chuàng)建這個module.
點擊File菜單,New --> New Module --> Android Library,輸入要創(chuàng)建的Module Name等信息。創(chuàng)建成功后會在我們的工程中多了個module目錄結(jié)構(gòu),如圖1所示。


圖1

2. 新建AIDL接口

右擊Module Java包文件夾,新建IAidlJarTest.aidl接口,隨便寫個接口函數(shù)

package tech.onroad.aidljar;
interface IAidlJarTest {
    void add(int a, int b);
}

重新編譯,同樣會在如下目錄生成對應的Java文件,如圖2所示


圖2

3. 添加引用module編譯

在app module的build.gradle文件dependencies中添加一行compile project(':aidljar'),使得app module依賴我們的AidlJar module。

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile project(':aidljar')
}

這樣就可以在app module中調(diào)用剛才的IAidlJarTest.aidl的接口了。

4. 新建一個Service來實現(xiàn)aidl接口

具體如何創(chuàng)建Service及實現(xiàn)接口方法請參考《跨進程間如何進行AIDL IPC 通信(一)》第一節(jié)。
創(chuàng)建AidlJarService并實現(xiàn)add()接口,代碼如下:

public class AidlJarService extends Service {
    public final String TAG = "AidlJarService";
    public AidlJarService() {
    }

    private IAidlJarTest.Stub mBinder = new IAidlJarTest.Stub() {

        @Override
        public void add(int a, int b) throws RemoteException {
            Log.d(TAG, "Add result: " + (a + b));
        }
    };

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

還有別忘了在AndroidManifest.xml注冊該service.

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

5. 編寫生成Jar包腳本

劃重點了^^
在Module aidljar的build.gradle加入如下腳本:

task makeAidlJar(type: Copy) {
    //delete exist jar library
    delete 'build/libs/aidltest.jar'
    //copy from file path
    from('build/intermediates/bundles/release/')
    //to dist file path
    into('build/libs/')
    include('classes.jar')
    rename ('classes.jar', 'aidltest.jar')
}

makeAidlJar.dependsOn(build)

然后在AS的Terminal執(zhí)行命令:gradlew makeAidlJar
BUILD SUCCESSFUL 后就會生成aidltest.jar
如下圖3所示


圖3

至此Service端和Jar library都已生成成功。接下來我們將嘗試一下在client端引用這個jar包,看能不能正常調(diào)用。

6. 在client端引入該jar包庫

將service端生成的aidltest.jar復制到AidlClientDemo工程中的app/libs/目錄下,如圖4所示


圖4

右擊aidltest.jar,選擇Add As Library...
接下來我們就可以正常調(diào)用該庫的接口了。

7. 調(diào)用jar包庫的接口

為了方便,我直接在client端工程MainActivity.java修改. 具體步驟可參考《跨進程間如何進行AIDL IPC 通信(一)》的第二節(jié),編碼完成后如下

private IAidlJarTest mIAidlJarTest;
ServiceConnection aidlServiceconn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        mIAidlJarTest = IAidlJarTest.Stub.asInterface(iBinder);
        try {
            mIAidlJarTest.add(8, 8);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        mIAidlJarTest = null;
    }
};
@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);

    //Test aidl jar service
    mServiceIntent.setAction("tech.onroad.aidlservicedemo.aidljarservice");
    mServiceIntent.setPackage("tech.onroad.aidlserverdemo");
    bindService(mServiceIntent, aidlServiceconn, Context.BIND_AUTO_CREATE);
}

8. 測試運行

將兩個apk push到模擬器運行,Log 控制臺輸入如下log


圖5

運行結(jié)果與我們預期一致,說明Client成功調(diào)用aidltest.jar的接口。

完整代碼可到我的github下載:

https://github.com/onroadtech/AidlDemo

-----完-----

更多博文可訪問我的個人網(wǎng)站:www.onroad.tech
歡迎指定,共同進步,指定郵箱: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)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • Android跨進程通信IPC整體內(nèi)容如下 1、Android跨進程通信IPC之1——Linux基礎2、Andro...
    隔壁老李頭閱讀 10,967評論 13 43
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,828評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評論 19 139
  • AIDL是Android跨進程間的一種非常重要的IPC通信機制,今天我們將來詳細講述如何不同app之間如何進行AI...
    onroad_tech閱讀 656評論 0 1
  • 《詩經(jīng)》里有很多“征夫淚”和“相思情”,我對《王風 小雅 君子于役》印象很深,腦海里一直浮現(xiàn)這樣的畫面:落日西山,...
    采之言閱讀 1,019評論 0 2

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