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
事先说明:
本人也是个初学者,所以本文是从初学者的角度入手,如果有不妥的地方请留言教导我,谢谢。
如果对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
相关文章推荐
- Android基础——Binder连接池连接多个AIDL文件的处理
- AIDL使用及Binder连接池
- web程序通过dbcp连接池处理自动重新连接数据库问题(通过连接池dbcp处理方案)
- IPC机制——AIDL——Binder“连接池”
- Binder底层原理,aidl.java文件分析
- java redis client无法连接redis服务获取连接池问题处理记录
- 关于IBatisNet的配置文件中数据库连接字符串加密处理
- 数据库连接从每次建立连接到配置文件的解耦和连接池的使用
- 建配置文件方法以及处理编码集为UTF-8步骤 Oracle数据库的连接配置内含读取配置类
- 基于binder机制编写aidl接口文件
- awk 如何处理两个文件,实现类似数据库表连接的操作
- linux文件处理命令-软连接
- 通过bat文件 进行mysql 连接 或者 操作涉及 密码的,如果密码 中有 % 号的话要特殊处理
- AIDL学习(三)---Binder连接池
- Apache DBCP连接池获取数据库连接慢的优化处理
- wp7模拟器开启不了,显示“被调用的对象已与其客户端断开连接”或者“接口”。并且提示有文件损坏的处理方法
- awk 如何处理两个文件,实现类似数据库表连接的操作
- window利用ssh连接上传文件及解压及乱码问题的一系列处理
- Binder连接池——教你如何更好地管理你的AIDL
- 使用连接池和缓存机制,处理连接数据库操作