关于Android aidl跨进程通信

一个应用需要与另外一个通讯,实现方法有很多,android 简单记录下实现

1.为什么要使用Binder?

  性能方面更加高效。Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式比较复杂。安全方面,Binder机制从协议本身就支持对通信双方做身份校检,因而大大提升了安全性。

2.为什么需要AIDL?

  使用简单。客户端和服务端进行通讯,若直接使用Binder需先将请求转换成序列化的数据,然后调用transact()函数发送给服务端,并且控制参数顺序,服务端和客户端都必须一致,否则就会出错。这样的过程很麻烦,如果有上百个接口,并且都需要手动编写传输接口,那可就很麻烦了。AIDL调用服务端方法如调用自身方法一样简单快捷烦。

1、server:右键新建一个AIDl 文件 ,随便定义2个方法,方法定义完毕Build一下生成 IXmInterface.Stub

2.server:创建Server,并返回IBinder!!如果 xxx.Stub() 无法引入,你可能是没有Rebuild 

public class XmServer extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //2.返回实现操作类
        return iBinder;
    }

    //1.创建IXmInterface的实现。。
    private IBinder iBinder = new IXmInterface.Stub() {

        //这里就是你要帮 client端实现的东西

        @Override
        public String getName() throws RemoteException {
            return "aidl name";
        }

        @Override
        public String getVersion() throws RemoteException {
            return "v1.0.0";
        }
    };
}

3.服务端server:配置服务,在单独的进程使用服务,允许外部打开exported=true 

 <service
            android:name=".server.XmServer"
            android:exported="true"
            android:process=":remote" />

 4.client:将服务器的aild拷贝到 客户端里面来,aidl层级跟 Java同层,完事记得ReBuild下

 5.client: 绑定并调用,并释放。

 //在需要的地方,开启aidl服务
        Intent intent = new Intent();
        intent.setClassName("com.frank.ffmpeg",
                "com.frank.ffmpeg.server.XmServer");
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    IXmInterface iXmInterface;
    boolean isConnected;
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iXmInterface = IXmInterface.Stub.asInterface(service);
            try {
                isConnected = true;
                MLog.e("服务连接成功:服务名称" + iXmInterface.getName() + ",服务版本:" + iXmInterface.getVersion());
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isConnected = false;
            iXmInterface = null;
            MLog.e("绑定结束");
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isConnected) {
            unbindService(mConnection);
        }
    }

ps:在targetSdkVersion>=30的时候可能出现绑定不成功,需要在Manifest添加该标签,预指我需要跟谁进行交互

<queries>
        <package android:name="com.frank.ffmpeg" />

        <!--如果有多个的话就添加多个标签-->
        <package android:name="com.tencent.mm" />
</queries>

猜你喜欢

转载自blog.csdn.net/masai158/article/details/125426929
今日推荐