设为首页 加入收藏

TOP

从AIDL开始谈Android进程间Binder通信机制(二)
2015-08-31 21:23:17 来源: 作者: 【 】 浏览:87
Tags:AIDL 开始 Android 进程 Binder 通信 机制
? ? mUnbind.setOnClickListener(
this);
? ? ? ? mAdd.setOnClickListener(
this);
? ? ? ? mMinus.setOnClickListener(
this);
? ? }

? ? @Override
? ?
protected void onStop() {

? ? ? ?
super.onStop();
? ? ? ? unbind();
? ? }

? ?
private void unbind(){
? ? ? ?
if (binded){
? ? ? ? ? ? unbindService(mConnection);
? ? ? ? ? ? binded
=false;
? ? ? ? }
? ? }

? ? @Override
? ?
public void onClick(View v) {
? ? ? ?
int id=v.getId();
? ? ? ?
switch (id){
? ? ? ? ? ?
case R.id.btn_bind:
? ? ? ? ? ? ? ? Intent intent
=new Intent();
? ? ? ? ? ? ? ? intent.setAction(
"com.cqumonk.adil.calculate");
? ? ? ? ? ? ? ? bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
? ? ? ? ? ? ? ?
break;
? ? ? ? ? ?
case R.id.btn_unbind:
? ? ? ? ? ? ? ? unbind();
? ? ? ? ? ? ? ?
break;
? ? ? ? ? ?
case R.id.btn_add:
? ? ? ? ? ? ? ?
if(mCalculateAIDL!=null){
? ? ? ? ? ? ? ? ? ?
try {
? ? ? ? ? ? ? ? ? ? ? ?
int res=mCalculateAIDL.add(3,3);
? ? ? ? ? ? ? ? ? ? ? ? txt_res.setText(res
+"");
? ? ? ? ? ? ? ? ? ? }
catch (RemoteException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
else{
? ? ? ? ? ? ? ? ? ? Toast.makeText(
this,"please rebind",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
break;
? ? ? ? ? ?
case R.id.btn_minus:
? ? ? ? ? ? ? ?
if(mCalculateAIDL!=null){
? ? ? ? ? ? ? ? ? ?
try {
? ? ? ? ? ? ? ? ? ? ? ?
int res=mCalculateAIDL.minus(9,4);
? ? ? ? ? ? ? ? ? ? ? ? txt_res.setText(res
+"");
? ? ? ? ? ? ? ? ? ? }
catch (RemoteException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
else{
? ? ? ? ? ? ? ? ? ? Toast.makeText(
this,"please rebind",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
break;
? ? ? ? }
? ? }
? ?
private ServiceConnection mConnection=new ServiceConnection() {
? ? ? ? @Override
? ? ? ?
public void onServiceConnected(ComponentName name, IBinder service) {
? ? ? ? ? ? Log.e(TAG,
"connect");
? ? ? ? ? ? binded
=true;
? ? ? ? ? ? mCalculateAIDL
=ICalculateAIDL.Stub.asInterface(service);

? ? ? ? }

? ? ? ? @Override
? ? ? ?
public void onServiceDisconnected(ComponentName name) {
? ? ? ? ? ? Log.e(TAG,
"disconnect");
? ? ? ? ? ? mCalculateAIDL
=null;
? ? ? ? ? ? binded
=false;
? ? ? ? }
? ? };
}


当我们点击绑定按钮,观察日志:



点击加法和减法按钮,都可以完成计算并返回值。然后点击解绑按钮:



我们并未发现有连接断开的日志打印,这时候,我们继续点击加减法按钮,发现仍然可以完成计算功能,这又是为毛呢?我们看到unbind和destroy的日志打印,说明连接已经断开,service已经被销毁,但是我们返回的stub对象仍然是可以继续使用的。而并不是说service仍然在运行。


过程分析


首先,我们调用bindservice方法来启动了service:


一方面连接成功时调用了serviceConnection的onServiceConnected方法。我们从该方法中获取到一个Binder对象(注意,这个binder并不是我们在service中实现的那个哦。当service时本apk中的service时,这里返回的是同一个binder),我们通过此binder来与server进行通信。为了区分,我们称为clientBinder。


public void onServiceConnected(ComponentName name, IBinder service) {
? ? ? ? ? ? Log.e(TAG,"connect");
? ? ? ? ? ? binded=true;
? ? ? ? ? ? mCalculateAIDL= ICalculateAIDL.Stub.asInterface(service);? ? ?
}


? ? ? ? 另一方面,onBind方法返回了我们实现的Stub对象,其实也是一个Binder,用于和Client进行通信。(之前我们定义了一个aidl接口文件,并根据它生成了ICalculateAIDL接口。这个接口中有我们定义的两个方法以及一个静态抽象内部类Stub,它是一个Binder的子类。)我们来看一下Stub是如何定义的:


public static abstract class Stub extends android.os.Binder implements com.cqumonk.calculate.aidl.ICalculateAIDL


? ? ? ? 它继承了Binder类也实现了ICalculateAIDL接口,我们实现了定义的add和minus方法。我们仍然要强调一下它并不是clientBinder,在负责与clientBinder进行通信交互的同时,它也维护了service描述符与服务端service的映射。


? ? ? ? 我们在Client中的onServiceConnected里调用了stub对象的asInterface方法,并将之前得到的clientBinder传入:


public static com.cqumonk.calculate.aidl.ICalculateAIDL asInterface(android.os.IBinder obj) {
? ? ? ? ? ? if ((obj == null)) {
? ? ? ? ? ? ? ? return null;
? ? ? ? ? ? }
? ? ? ? ? ? android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);//根据包名获取本地实现的一个接口的实例,如果是本地service则可以获

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇使用Visual Studio 2015开发Andro.. 下一篇Android线程间异步通信机制源码分..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: