Android aidl一个service同时绑定多个客户端client

一、场景

最近开发过程中,遇到了这样的场景,aidl在service和client通信的过程中,一个service需要同时绑定多个client进行通信。

一开始我的想法是:

这种写法绑定多个客户端是有问题的,绑定了一个没有解绑的话,其他client是不会走这个onBind方法。

因为这是Android四大组件之一的Service的机制决定的。一个service经过bindService之后,再次去bindService,是不会再走onBind回调的。

二、解决办法(一个Service返回多种Binder的能力)

为了减少Service占用资源,应该尽量减少Service的数量,而Service的onBind方法再被绑定后会返回一个Binder,如果没有解绑,就不会再执行onBind方法了,所以即使第二次再intent中传入了不同类型的来获取新的Binder,也是不成功的。

解决的方法:Service返回一个工厂类binder,通过这个工厂类binder来生成不同的binder即可。

首先创建一个IBinderFactory.aidl

interface IBinderFactory {
    IBinder generateBinder(int binderType);
}

在Binder实现类中,根据binderType返回不同的Binder,具体代码如下:

    @Override
    public IBinder onBind(Intent intent) {
        return new BinderFactory();
    }

    class BinderFactory extends IBinderFactory.Stub {

        @Override
        public IBinder generateBinder(int binderType) throws RemoteException {
            IBinder binder;
            switch (binderType) {
                case TYPE_MY_BINDER:
                default:
                    binder = new MyBinder();

            }
            return binder;
        }
    }

客户端先获得BinderFactory,再获得MyBinder

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //在服务连接成功后进行调用
            IBinderFactory iBinderFactory = IBinderFactory.Stub.asInterface(service);
            IMyAidlInterface iMyAidlInterface = null;
            try {
                iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinderFactory.generateBinder(TYPE_MY_BINDER));
            } catch (RemoteException e) {
                e.printStackTrace();
            }
    }

客户端demo地址:https://github.com/sunbinkang/AIDLClient/tree/t0

服务端demo地址:​​​​​​​https://github.com/sunbinkang/AIDLService/tree/t0

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
好的,以下是一个简单的 Android AIDL 示例代码: 首先,需要定义一个 AIDL 接口文件,例如 MyService.aidl: ``` package com.example.myservice; interface MyService { String getMessage(); } ``` 然后在服务端实现这个接口,例如 MyService.java: ``` package com.example.myservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service { private final MyServiceImpl mImpl = new MyServiceImpl(); private static class MyServiceImpl extends IMyService.Stub { @Override public String getMessage() { return "Hello from MyService!"; } } @Override public IBinder onBind(Intent intent) { return mImpl; } } ``` 最后,在客户端绑定服务并调用接口方法,例如 MainActivity.java: ``` package com.example.myapplication; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.myservice.MyService; public class MainActivity extends AppCompatActivity { private MyService mService; private boolean mBound = false; private final ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = MyService.Stub.asInterface(service); mBound = true; // 调用 MyService 中定义的接口方法 try { String message = mService.getMessage(); TextView textView = findViewById(R.id.text_view); textView.setText(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { mService = null; mBound = false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 绑定 MyService Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.myservice", "com.example.myservice.MyService")); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); if (mBound) { unbindService(mConnection); mBound = false; } } } ``` 鉴于这只是一个简单的示例,实际的应用场景可能会更加复杂。需要注意的是,AIDL 接口中定义的方法的参数和返回值必须是支持跨进程传输的类型,例如基本类型、String、Parcelable 等。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值