Android基础——Binder连接池连接多个AIDL文件的处理

Binder连接池连接多个AIDL文件的处理


事先说明:

本人也是个初学者,所以本文是从初学者的角度入手,如果有不妥的地方请留言教导我,谢谢。

如果对AIDL的使用和Binder机制不懂的,可以参照我之前的文章,Android基础——初学者必知的AIDL在应用层上的Binder机制http://blog.csdn.net/qq_30379689/article/details/52253413


前言:

按照我们之前的对AIDL的使用方法,必须满足一个AIDL接口对应一个service。假如我们的应用,有多个模块需要多个AIDL,则需要多个Service端,Service作为四大组件,内存占用高,这样就影响了应用程序的性能了。所以我们需要将所有的AIDL放入一个Service中去管理。

欢迎关注我的CSDN博客,Hensen_的博客,http://blog.csdn.net/qq_30379689


Binder连接池工作原理:



服务端的操作

步骤一:创建两个模块需要的aidl文件和创建一个Binder连接池aidl文件,编译一下Gradle


interface IMyAidlInterface {
    int add(int num1,int num2);
}

interface IMyAidl2Interface {
     String print_A();
     String print_B();
}
interface IMyBinderPoolInterface {
     IBinder queryBinder(int binderCode);
}
步骤二:创建两个模块对aidl文件的实现类和创建一个Binder连接池类并实现,创建一个服务端

public class IMyAidlImpl extends IMyAidlInterface.Stub {
    @Override
    public int add(int num1, int num2) throws RemoteException {
        return num1 + num2;
    }
}
public class IMyAidl2Impl extends IMyAidl2Interface.Stub {
    @Override
    public String print_A() throws RemoteException {
        return "A";
    }

    @Override
    public String print_B() throws RemoteException {
        return "B";
    }
}
public class BinderPool {
    //获取AIDL代理对象的标识
    private static final int BINDER_1 = 0;
    private static final int BINDER_2 = 1;

    /**
     * 实现AIDL接口的方法
     */
    public static class IMyBinderPoolImpl extends IMyBinderPoolInterface.Stub {

        @Override
        public IBinder queryBinder(int binderCode) throws RemoteException {
            IBinder binder = null;
            switch (binderCode) {
                case BINDER_1:
                    binder = new IMyAidlImpl();
                    break;
                case BINDER_2:
                    binder = new IMyAidl2Impl();
                    break;
                default:
                    break;
            }
            return binder;
        }
    }
}
public class MyService extends Service {

    private Binder myBinder  = new BinderPool.IMyBinderPoolImpl();

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

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}
步骤三:在manifests中配置Service

<service
            android:name=".Aidl.MyService"
            android:exported="true" />
步骤四:在代码中启动服务

public class LoginActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        startService(new Intent(this, MyService.class));
    }
}


客户端的操作
步骤一:复制服务端的aidl文件到客户端中,编译一下Gradle


步骤二:编写Binder连接池的代码,解释在代码中

public class BinderPool {

    //上下文
    private Context mContext;
    //同步辅助类
    private CountDownLatch mCountDownLatch;
    //单例
    private static BinderPool mInstance;
    //获取AIDL代理对象的标识
    public static final int BINDER_1 = 0;
    public static final int BINDER_2 = 1;

    private IMyBinderPoolInterface mBinderPoolInterface;

    private BinderPool(Context context) {
        //获取上下文
        mContext = context.getApplicationContext();
        //连接远程服务
        connectBinderPoolService();
    }

    /**
     * 单例模式
     *
     * @param context
     * @return
     */
    public static BinderPool getInstance(Context context) {
        if (mInstance == null) {
            synchronized (BinderPool.class) {
                if (mInstance == null) {
                    mInstance = new BinderPool(context);
                }
            }
        }
        return mInstance;
    }

    /**
     * 提供该类的一个查询方法
     *
     * @param binderCode
     * @return
     */
    public IBinder queryBinder(int binderCode) {
        IBinder binder = null;
        try {
            if (mBinderPoolInterface != null) {
                binder = mBinderPoolInterface.queryBinder(binderCode);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return binder;
    }

    /**
     * 开启远程服务,并保持同步
     */
    private synchronized void connectBinderPoolService() {
        //同步辅助器,值为1
        mCountDownLatch = new CountDownLatch(1);
        //开启远程服务
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.handsome.boke", "com.handsome.boke.Aidl.MyService"));
        mContext.bindService(intent, conn, mContext.BIND_AUTO_CREATE);
        try {
            //同步辅助器
            mCountDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接服务器接口
     */
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinderPoolInterface = IMyBinderPoolInterface.Stub.asInterface(service);
            //绑定死亡监听
            try {
                mBinderPoolInterface.asBinder().linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            //同步辅助器,值减1
            mCountDownLatch.countDown();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    /**
     * 死亡监听接口,如果Binder对象在使用过程中突然停止服务,就会返回这个接口
     */
    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            //取消死亡监听
            mBinderPoolInterface.asBinder().unlinkToDeath(mDeathRecipient, 0);
            //释放资源
            mBinderPoolInterface = null;
            //重新连接服务
            connectBinderPoolService();
        }
    };

}
步骤三:代码中使用

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                //如果这里不用子线程,会导致ANR错误,因为服务器的连接是个耗时的任务
                startBinderPool();
            }
        }).start();
    }

    private void startBinderPool() {
        BinderPool binderPool = BinderPool.getInstance(this);
        //第一个模块
        IBinder binder2 = binderPool.queryBinder(BinderPool.BINDER_2);
        IMyAidl2Interface myAidl2Interface = IMyAidl2Interface.Stub.asInterface(binder2);
        try {
            String str1 = myAidl2Interface.print_A();
            String str2 = myAidl2Interface.print_B();
            Log.i("————————————", "Aidl2的结果:" + str1);
            Log.i("————————————", "Aidl2的结果:" + str2);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        //第二个模块
        IBinder binder = binderPool.queryBinder(BinderPool.BINDER_1);
        IMyAidlInterface myAidlInterface = IMyAidlInterface.Stub.asInterface(binder);
        try {
            int res = myAidlInterface.add(1, 3);
            Log.i("————————————", "Aidl1的计算结果:" + res);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}
步骤四:启动服务端,然后启动客户端,查看Log,测试结果
08-25 00:13:04.025 3538-3566/com.handsome.app2 I/————————————: Aidl2的结果:A
08-25 00:13:04.025 3538-3566/com.handsome.app2 I/————————————: Aidl2的结果:B
08-25 00:13:04.028 3538-3566/com.handsome.app2 I/————————————: Aidl1的计算结果:4














  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许英俊潇洒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值