您的位置:首页 > 大数据 > 人工智能

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

2017-04-02 17:18 204 查看
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






[java] view
plain copy

interface IMyAidlInterface {  

    int add(int num1,int num2);  

}  

[java] view
plain copy

interface IMyAidl2Interface {  

     String print_A();  

     String print_B();  

}  

[java] view
plain copy

interface IMyBinderPoolInterface {  

     IBinder queryBinder(int binderCode);  

}  

步骤二:创建两个模块对aidl文件的实现类和创建一个Binder连接池类并实现,创建一个服务端

[java] view
plain copy

public class IMyAidlImpl extends IMyAidlInterface.Stub {  

    @Override  

    public int add(int num1, int num2) throws RemoteException {  

        return num1 + num2;  

    }  

}  

[java] view
plain copy

public class IMyAidl2Impl extends IMyAidl2Interface.Stub {  

    @Override  

    public String print_A() throws RemoteException {  

        return "A";  

    }  

  

    @Override  

    public String print_B() throws RemoteException {  

        return "B";  

    }  

}  

[java] view
plain copy

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;  

        }  

    }  

}  

[java] view
plain copy

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

[java] view
plain copy

<service  

            android:name=".Aidl.MyService"  

            android:exported="true" />  

步骤四:在代码中启动服务

[java] view
plain copy

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连接池的代码,解释在代码中

[java] view
plain copy

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();  

        }  

    };  

  

}  

步骤三:代码中使用

[java] view
plain copy

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,测试结果

[java] view
plain copy

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  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: