AIDL是什么 ?

AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,AIDL的作用是让你可以在自己的APP里绑定一个其他APP的service,这样你的APP可以和其他APP交互

为什么要有aidl ?

用于两个App之间交换数据的场景 为什么不能直接通讯? 在 Android 上,一个进程通常无法访问另一个进程的内存, 而AIDL只是Android中众多进程间通讯方式中的一种方式

使用方法

服务端AidlApp1

  1. 使用Android Studio在Service服务端创建aidl文件: IUserAidlInterface, 然后build一下
package com.joshkryo.aidl;

interface IUserAidlInterface {
    String getUserInfo(int uid);
}
  1. 创建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}";
        }
    };
}
  1. 注册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

  1. 复制AidlApp1的aidl文件到AidlApp2, build一下
  2. 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;
        }
    };
}
  1. 使用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();
        }
    }
}

可能的错误

  1. 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一定要显性声明
  2. onServiceConnected不调用 可能原因:
  • service 没有在manifest里面注册
  • 服务端, 客户端的 intent action 不一致