前言
想想一下这样一种场景,我们在模块化开发某个功能的时候,我们不想吧核心的代码曝露出去,而且也没办法曝露出某些代码。例如:某第三方要提供给一些功能给外部。在比如,上层APP的开发者需要用到某手机专属的某一功能A,但该手机厂商又没有对外发布sdk(或者jar包)。本文介绍的AIDL机制理论上可以解决该问题。
创建Android Studio Project
这里不描述是如何step by step创建 project,最终结果如下图所示。其中aidl 是module名称,在下一节介绍
创建AIDL module
对应的module创建成功之后,创建一个AIDL文件,一个service文件;在service文件中实现AIDL的接口调用
IMyAidlInterface.aidl
// IMyAidlInterface.aidl
package cp.com.aidl;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
String getStr();
boolean setStatus(int aInt);
}
MyAIDLService.java
package cp.com.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyAIDLService extends Service {
private static final String TAG=MyAIDLService.class.getSimpleName();
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//throw new UnsupportedOperationException("Not yet implemented");
return mBinder;
}
private final IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
@Override
public String getStr() throws RemoteException {
Log.e(TAG,"this from AIDL service ...getStr..");
return TAG;
}
@Override
public boolean setStatus(int aInt) throws RemoteException {
Log.e(TAG,"this from AIDL service ...setStatus..="+aInt);
return (aInt%2 == 0);
}
};
}
需要注意的一点是,在实现module的aidl代码时,完成aidl代码的编写之后需要讲module build下。否则可能会出现找不到包名的情况。
好,至此我们讲AIDL的实现部分使用Android studio 的module来实现;接下来我们在app中来调用对应的服务。
客户端调用AIDL服务
创建客户端aidl文件
首先在/path/to/application/app/src/main目录下创建一个aidl目录(名字任意)
接着创建一个同.aidl
文件相同的包名,并将aidl文件拷贝到该包名下;例如这里的cp.com.aidl
绑定service
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MyAIDLService.class);
bindService(intent,conn,Service.BIND_AUTO_CREATE);
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mAIDLService = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mAIDLService = null;
}
};
private void updateTextView(){
String str = null;
boolean status = false;
try {
str = mAIDLService.getStr();
status = mAIDLService.setStatus(count);
count++;
} catch (RemoteException e) {
e.printStackTrace();
}
aidlTextView.setText(str+status);
}
确认APP同 module的依赖关系
编译运行
后话
IPC用处还是多多的。。
后续,当有某一功能即是必须要曝露给第三方,但是又不能给核心代码,编译jar包扔进APP又太繁琐。这里提供了一个可选择的方案