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
步骤四:在代码中启动服务
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));
}
}
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