AIDL是什么 ?
AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,AIDL的作用是让你可以在自己的APP里绑定一个其他APP的service,这样你的APP可以和其他APP交互
为什么要有aidl ?
用于两个App之间交换数据的场景 为什么不能直接通讯? 在 Android 上,一个进程通常无法访问另一个进程的内存, 而AIDL只是Android中众多进程间通讯方式中的一种方式
使用方法
服务端AidlApp1
- 使用Android Studio在Service服务端创建aidl文件: IUserAidlInterface, 然后build一下
package com.joshkryo.aidl;
interface IUserAidlInterface {
String getUserInfo(int uid);
}
- 创建Service实现类
public class UserAidlService extends Service {
private static final String TAG = "UserAidlService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: " + intent);
return mBinder;
}
private final IUserAidlInterface.Stub mBinder = new IUserAidlInterface.Stub() {
@Override
public String getUserInfo(int uid) throws RemoteException {
return "{\"id\":" + uid + " ,name\":\"Tom\",\"age\":18}";
}
};
}
- 注册Service
<service
android:name="com.joshkryo.aidlapp1.service.UserAidlService"
android:enabled="true">
<intent-filter>
<action android:name="com.joshkryo.aidlapp1.service.UserAidlService"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
客户端AidlApp2
- 复制AidlApp1的aidl文件到AidlApp2, build一下
- bindService
class BindService {
private void bindAidlService() {
Intent intent = new Intent("com.joshkryo.aidlapp1.service.UserAidlService");// service配置的action
intent.setPackage("com.joshkryo.aidlapp1");//service服务端包名
bindService(intent, mAidlConn, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mAidlConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected");
userAidlInterface = IUserAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "onServiceDisconnected: ");
userAidlInterface = null;
}
};
}
- 使用aidl interface调用AidlApp1里的service
class Test {
public void getAidlUserInfo(View v) {
try {
if (userAidlInterface == null) {
Log.e(TAG, "onClick: null userAidlInterface instance");
return;
}
Toast.makeText(MainActivity.this, userAidlInterface.getUserInfo(1), Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
可能的错误
- Service Intent must be explicit java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.joshkryo.aidlapp1 } at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2854) 原因: Android5.0之后service的intent一定要显性声明
- onServiceConnected不调用 可能原因:
- service 没有在manifest里面注册
- 服务端, 客户端的 intent action 不一致