在android中进程间通信(IPC)的基石是Binder系统,Binder系统的核心Binder驱动是C来实现的,对于应用开发人员来说无疑晦涩难懂,而整个android框架是基于面向对象思想的,对于底层Binder驱动的操作细节全部隐藏,framework层提供了一个牛逼无比的Binder对象, 所以我们要实现进程间通信(IPC)只需玩转Binder对象即可。

在android源码中基于Binder对象的通信随处可见,几乎可以认定为以 I 打头的class,都具有进程间通信能力,如:IServiceManager,IContentProvider等。

在源码中实现的方式也可概括为两种:

1. 通过aidl来生成对Binder的操作。

2.手动调用IBinder.transact编写按照顺序写入与读出的parcel代码实现。

第一种方法网上案例较多,不多说。第二种方法实现源码参考:ActivityManagerNative,ActivityManagerProxy

关于第二种方法的实现本人做了一个demo,请看以下代码。


packagedw.test;importjava.util.HashMap;importandroid.os.Binder;importandroid.os.IBinder;importandroid.os.IInterface;importandroid.os.Parcel;importandroid.os.RemoteException;importandroid.util.Log;/***负责接收指令({@linkCmdCode}),并将指令派发到相应的处理器({@linkCmdDispatcher.Callback})*/publicfinalclassCmdDispatcherextendsBinderimplementsIInterface{privatestaticfinalStringLOG_TAG=CmdDispatcher.class.getSimpleName();publicstaticfinalStringDESCRIPTOR=CmdDispatcher.class.getName();/***存储所有指令处理器*map.key={@linkCmdCode}*/privateHashMap<Integer,Callback>mCallbacks=newHashMap<Integer,Callback>();/***针对某个指令的处理*@see#addCallback*@see#removeCallback*/publicinterfaceCallback{/***@paramcode请求指令集{@linkCmdCode.Request},响应指令集{@linkCmdCode.Response}*@paramdata数据{@linkParcel}*@paramreply处理data的结果{@linkParcel}*@return*/publicbooleanonTransact(intcode,Parceldata,Parcelreply);}/***当client端调用{@linkIBinder#transact(int,Parcel,Parcel,int)}时,将会回调本方法。*/@OverrideprotectedbooleanonTransact(intcode,Parceldata,Parcelreply,intflags)throwsRemoteException{dispatch(code,data,reply);returntrue;}/***得到某个指令处理器并调用*/privatevoiddispatch(intcode,Parceldata,Parcelreply){Log.i(LOG_TAG,"dispatchreplyenter");Callbackcallback=mCallbacks.get(code);if(callback!=null){callback.onTransact(code,data,reply);}Log.i(LOG_TAG,"dispatchreplyexit");}@OverridepublicIBinderasBinder(){returnthis;}@OverridepublicStringgetInterfaceDescriptor(){returnDESCRIPTOR;}@OverridepublicIInterfacequeryLocalInterface(Stringdescriptor){returnthis;}/***针对某一个指令,如:请求指令集{@linkCmdCode.Request},响应指令集{@linkCmdCode.Response}*添加回调处理*@paramcode指令编码*@paramcallback针对某一个指定的处理{@linkCallback}*/publicvoidaddCallback(intcode,Callbackcallback){mCallbacks.put(code,callback);}publicvoidremoveCallback(intcode){mCallbacks.remove(code);}}


packagedw.test;/***定义指令集*/publicinterfaceCmdCode{publicinterfaceBaseCode{/***每个parcel的头*/publicstaticfinalintPARCEL_HEAD=0xffff;publicstaticfinalintRESULT_SUCCESS=0x0001;publicstaticfinalintRESULT_ERROR=0x0002;}/***请求指令集*/publicinterfaceRequestextendsBaseCode{publicstaticfinalintREQUEST=0x0001;}/***响应指令集*/publicinterfaceResponseextendsBaseCode{publicstaticfinalintRESPONSE=0x0001;}}


packagedw.test;importdw.test.CmdDispatcher.Callback;importandroid.app.Service;importandroid.content.Intent;importandroid.os.IBinder;importandroid.os.Parcel;importandroid.util.Log;/***RemoteService作为一个独立进程存在.*/publicclassRemoteCmdServiceextendsServiceimplementsCallback,CmdCode.Request{privatestaticfinalStringLOG_TAG=RemoteCmdService.class.getSimpleName();privatefinalCmdDispatchermCmdDispatcher=newCmdDispatcher();@OverridepublicIBinderonBind(Intentintent){mCmdDispatcher.addCallback(REQUEST,this);returnmCmdDispatcher;}@OverridepublicvoidonCreate(){super.onCreate();}@OverridepublicintonStartCommand(Intentintent,intflags,intstartId){Log.i(LOG_TAG,"onStartCommandenter");returnsuper.onStartCommand(intent,flags,startId);}@OverridepublicbooleanonTransact(intcode,Parceldata,Parcelreply){Log.i(LOG_TAG,"removeservicehandleReplyenter");data.enforceInterface(CmdDispatcher.DESCRIPTOR);//读取包头inthead=data.readInt();if(head==PARCEL_HEAD){StringhandeResult=data.readString();reply.writeInt(RESULT_SUCCESS);Log.i(LOG_TAG,handeResult);}else{reply.writeInt(RESULT_ERROR);}Log.i(LOG_TAG,"removeservicehandleReplyexit");returntrue;}}



packagedw.test.activity;importandroid.app.Activity;importandroid.content.ComponentName;importandroid.content.Intent;importandroid.content.ServiceConnection;importandroid.os.Bundle;importandroid.os.IBinder;importandroid.os.Parcel;importandroid.os.RemoteException;importandroid.util.Log;importandroid.view.View;importandroid.view.View.OnClickListener;importdw.test.CmdCode;importdw.test.CmdDispatcher;importdw.test.R;importdw.test.RemoteCmdService;publicclassMainActivityextendsActivityimplementsOnClickListener,CmdCode.Request,CmdCode.Response{privatestaticfinalStringLOG_TAG=MainActivity.class.getSimpleName();@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.findViewById(R.id.test_remote_binder_btn).setOnClickListener(this);}/***连接并调用远程服务*/privatevoidtestRemote(){Intentintent=newIntent(MainActivity.this,RemoteCmdService.class);//绑定远程服务bindService(intent,newServiceConnection(){@OverridepublicvoidonServiceDisconnected(ComponentNamename){}@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){replyTo(service);}},BIND_AUTO_CREATE);}privatevoidreplyTo(IBinderservice){Parceldata=Parcel.obtain();Parcelreply=Parcel.obtain();data.writeInterfaceToken(CmdDispatcher.DESCRIPTOR);//写入包头data.writeInt(PARCEL_HEAD);//写入要发送的字符数据data.writeString("serviceConnected");//当然你也可以传递一个binder对象过去作为callback,这样两个进程间就可以交互了。//data.writeStrongBinder(IBinderbinder);try{//调用远程MESSAGE_REQUEST服务service.transact(REQUEST,data,reply,0);}catch(RemoteExceptione){//ignore}//MESSAGE_REQUEST服务所返回的结果intresult=reply.readInt();if(RESULT_SUCCESS==result){Log.i(LOG_TAG,"ok");}data.recycle();reply.recycle();}@OverridepublicvoidonClick(Viewv){intid=v.getId();if(R.id.test_remote_binder_btn==id){testRemote();}}}


代码工程:http://download.csdn.net/detail/hacker686ok/5810399


更多相关文章

  1. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  2. android GC内存泄露问题
  3. Android(安卓)ANR分析
  4. android使用logwrapper进行log重定向
  5. Android(安卓)系统启动流程解析-从开机到Dalvik VM
  6. Android(安卓)内存查看常用命令
  7. 抖音BoostMultiDex优化实践:Android低版本上APP首次启动时间减少8
  8. Android(安卓)IPC 进程间通信实现理解
  9. Framework笔记 | Android(安卓)Framework用到了哪些IPC方式,分别

随机推荐

  1. android 获取wifi 信号质量
  2. android 弹出软盘
  3. android 判断联网类型
  4. Android(安卓)3rd-party libraries
  5. android联系人过滤
  6. Build Variants Android变体构建配置
  7. android网络状态检查
  8. Cocos2d-x & NDK
  9. Android(安卓)- ScrollView 使用小计 里
  10. 4. android 滚动视图