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

来源:互联网 发布:2017最新网络推广渠道 编辑:程序博客网 时间:2024/06/03 17:22

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的结果:A08-25 00:13:04.025 3538-3566/com.handsome.app2 I/————————————: Aidl2的结果:B08-25 00:13:04.028 3538-3566/com.handsome.app2 I/————————————: Aidl1的计算结果:4














2 0