在前三篇博客中,我們介紹了如何進(jìn)行AIDL IPC通信,代碼設(shè)計(jì)及AIDL數(shù)據(jù)傳輸?shù)念愋汀T诘谝黄┛痛a設(shè)計(jì)中,我們?cè)f(shuō)過(guò),需要將AIDL接口文件及對(duì)應(yīng)生成的Java文件要原封不動(dòng)拷貝到客戶端,這樣客戶端才能正常編譯執(zhí)行,但是這樣操作非常麻煩且不合理,所以今天我們將要介紹如何將AIDL接口文件及對(duì)應(yīng)生成的Java文件生成Jar包庫(kù),直接丟給第三方客戶端使用。嚴(yán)格意義上說(shuō),這篇博客不屬于AIDL IPC通信的范疇,但為了使整個(gè)AIDL IPC通信設(shè)計(jì)的連續(xù)性,我還是決定將其放到這里。同樣以前面的工程為例:
1. 創(chuàng)建Module
創(chuàng)建Module其實(shí)就是為了創(chuàng)建android lib庫(kù)。由于我們的AIDL接口是在service端設(shè)計(jì)的,且由service端對(duì)外提供,因此我們選擇在service端工程創(chuàng)建這個(gè)module.
點(diǎn)擊File菜單,New --> New Module --> Android Library,輸入要?jiǎng)?chuàng)建的Module Name等信息。創(chuàng)建成功后會(huì)在我們的工程中多了個(gè)module目錄結(jié)構(gòu),如圖1所示。
2. 新建AIDL接口
右擊Module Java包文件夾,新建IAidlJarTest.aidl接口,隨便寫(xiě)個(gè)接口函數(shù)
package tech.onroad.aidljar;
interface IAidlJarTest {
void add(int a, int b);
}
重新編譯,同樣會(huì)在如下目錄生成對(duì)應(yīng)的Java文件,如圖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. 新建一個(gè)Service來(lái)實(shí)現(xiàn)aidl接口
具體如何創(chuàng)建Service及實(shí)現(xiàn)接口方法請(qǐng)參考《跨進(jìn)程間如何進(jìn)行AIDL IPC 通信(一)》第一節(jié)。
創(chuàng)建AidlJarService并實(shí)現(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注冊(cè)該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. 編寫(xiě)生成Jar包腳本
劃重點(diǎn)了^^
在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 后就會(huì)生成aidltest.jar
如下圖3所示
至此Service端和Jar library都已生成成功。接下來(lái)我們將嘗試一下在client端引用這個(gè)jar包,看能不能正常調(diào)用。
6. 在client端引入該jar包庫(kù)
將service端生成的aidltest.jar復(fù)制到AidlClientDemo工程中的app/libs/目錄下,如圖4所示
右擊aidltest.jar,選擇Add As Library...
接下來(lái)我們就可以正常調(diào)用該庫(kù)的接口了。
7. 調(diào)用jar包庫(kù)的接口
為了方便,我直接在client端工程MainActivity.java修改. 具體步驟可參考《跨進(jìn)程間如何進(jìn)行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. 測(cè)試運(yùn)行
將兩個(gè)apk push到模擬器運(yùn)行,Log 控制臺(tái)輸入如下log
運(yùn)行結(jié)果與我們預(yù)期一致,說(shuō)明Client成功調(diào)用aidltest.jar的接口。
完整代碼可到我的github下載:
-----完-----
更多博文可訪問(wèn)我的個(gè)人網(wǎng)站:www.onroad.tech
歡迎指定,共同進(jìn)步,指定郵箱:onroad_tech@163.com