我相信稍微对android了解一点的人都知道Android系统进程之间是不能共享内存的。因此,需要一些机制来实现不同进程之间的数据交互。Android系统采用RPC方法来实现,实现RPC的服务我们称之为AIDL服务(Android Interface Definition Language)服务。

在这里我们将提供服务的一个应用程序称之为服务端,接受服务的一方叫做客户端。你首先得在服务端定义一个aidl文件,如下所示:

//IMyService.aidlpackagecom.weiweishen.docs.aidl;interfaceIMyService{StringgetValue();}

然后重新编译程序,系统会在gen目录自动生成一个IMyService.java文件,你不需要改动它,源代码如下:

//IMyService.java/**Thisfileisauto-generated.DONOTMODIFY.*Originalfile:/Users/wei/Documents/work/Docs/src/com/weiweishen/docs/aidl/IMyService.aidl*/packagecom.weiweishen.docs.aidl;publicinterfaceIMyServiceextendsandroid.os.IInterface{/**Local-sideIPCimplementationstubclass.*/publicstaticabstractclassStubextendsandroid.os.Binderimplementscom.weiweishen.docs.aidl.IMyService{privatestaticfinaljava.lang.StringDESCRIPTOR="com.weiweishen.docs.aidl.IMyService";/**Constructthestubatattachittotheinterface.*/publicStub(){this.attachInterface(this,DESCRIPTOR);}/***CastanIBinderobjectintoancom.weiweishen.docs.aidl.IMyServiceinterface,*generatingaproxyifneeded.*/publicstaticcom.weiweishen.docs.aidl.IMyServiceasInterface(android.os.IBinderobj){if((obj==null)){returnnull;}android.os.IInterfaceiin=obj.queryLocalInterface(DESCRIPTOR);if(((iin!=null)&&(iininstanceofcom.weiweishen.docs.aidl.IMyService))){return((com.weiweishen.docs.aidl.IMyService)iin);}returnnewcom.weiweishen.docs.aidl.IMyService.Stub.Proxy(obj);}@Overridepublicandroid.os.IBinderasBinder(){returnthis;}@OverridepublicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)throwsandroid.os.RemoteException{switch(code){caseINTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);returntrue;}caseTRANSACTION_getValue:{data.enforceInterface(DESCRIPTOR);java.lang.String_result=this.getValue();reply.writeNoException();reply.writeString(_result);returntrue;}}returnsuper.onTransact(code,data,reply,flags);}privatestaticclassProxyimplementscom.weiweishen.docs.aidl.IMyService{privateandroid.os.IBindermRemote;Proxy(android.os.IBinderremote){mRemote=remote;}@Overridepublicandroid.os.IBinderasBinder(){returnmRemote;}publicjava.lang.StringgetInterfaceDescriptor(){returnDESCRIPTOR;}@Overridepublicjava.lang.StringgetValue()throwsandroid.os.RemoteException{android.os.Parcel_data=android.os.Parcel.obtain();android.os.Parcel_reply=android.os.Parcel.obtain();java.lang.String_result;try{_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_getValue,_data,_reply,0);_reply.readException();_result=_reply.readString();}finally{_reply.recycle();_data.recycle();}return_result;}}staticfinalintTRANSACTION_getValue=(android.os.IBinder.FIRST_CALL_TRANSACTION+0);}publicjava.lang.StringgetValue()throwsandroid.os.RemoteException;}

这个步骤完成之后,你就可以通过继承IMyService.Stub(继承自Binder类,Android本质上利用Binder实现进程之间的交互)来实现提供服务的具体方法。

//IMyService.javapackagecom.weiweishen.docs;importandroid.app.Service;importandroid.content.Intent;importandroid.os.IBinder;importandroid.os.RemoteException;importcom.weiweishen.docs.aidl.IMyService;;publicclassMyServiceextendsService{inti=1;publicMyService(){}publicclassMyServiceImplextendsIMyService.Stub{@OverridepublicStringgetValue()throwsRemoteException{//TODOAuto-generatedmethodstubi++;return"helloeveryone"+i;}}@OverridepublicIBinderonBind(Intentintent){returnnewMyServiceImpl();}}

我们看上面代码,MyServiceImpl继承了IMyService.Stub。getValue()方法是我们提供给客户端的服务,在这里我们是返回一个字符串给客户端。onBinder方法返回一个Binder类,即我们继承IMyService.stub的MyServiceImpl的内部类。实现了这一步,我们服务器端的代码就写好了,下面我们看看客户端,另建一个android project,将IMyService文件连同包目录拷贝到客户端工程的src目录中,看下图,然后在MainActivity实现跨进程调用。

下面是MainActivity的代码:

//MainActivity.javapackagecom.weiweishen.docsclient;importcom.weiweishen.docs.aidl.IMyService;importandroid.app.Activity;importandroid.content.ComponentName;importandroid.content.Context;importandroid.content.Intent;importandroid.content.ServiceConnection;importandroid.os.Bundle;importandroid.os.IBinder;importandroid.os.RemoteException;importandroid.view.Menu;importandroid.view.MenuItem;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.Toast;publicclassMainActivityextendsActivityimplementsOnClickListener{IMyServicemyService=null;Buttonbtn1;Buttonbtn2;Buttonbtn3;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn1=(Button)findViewById(R.id.button1);btn2=(Button)findViewById(R.id.button2);btn3=(Button)findViewById(R.id.button3);btn1.setOnClickListener(this);btn2.setOnClickListener(this);btn3.setOnClickListener(this);}privateServiceConnectionserviceConnection=newServiceConnection(){@OverridepublicvoidonServiceDisconnected(ComponentNamename){//TODOAuto-generatedmethodstub}@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){//TODOAuto-generatedmethodstubmyService=IMyService.Stub.asInterface(service);}};@OverridepublicbooleanonCreateOptionsMenu(Menumenu){//Inflatethemenu;thisaddsitemstotheactionbarifitispresent.getMenuInflater().inflate(R.menu.main,menu);returntrue;}@OverridepublicbooleanonOptionsItemSelected(MenuItemitem){//Handleactionbaritemclickshere.Theactionbarwill//automaticallyhandleclicksontheHome/Upbutton,solong//asyouspecifyaparentactivityinAndroidManifest.xml.intid=item.getItemId();if(id==R.id.action_settings){returntrue;}returnsuper.onOptionsItemSelected(item);}@OverridepublicvoidonClick(Viewv){//TODOAuto-generatedmethodstubswitch(v.getId()){caseR.id.button1:bindService(newIntent("com.weiweishen.docs.aidl.IMyService"),serviceConnection,Context.BIND_AUTO_CREATE);break;caseR.id.button2:try{Toast.makeText(MainActivity.this,myService.getValue(),Toast.LENGTH_LONG).show();}catch(RemoteExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}break;caseR.id.button3:unbindService(serviceConnection);break;default:break;}}}

这里值得注意的是,服务器端的service必须是开启的,否则会报错。这里,按钮1开启服务,按钮2显示返回的数据,按钮3结束服务。

AIDL的介绍就到这里了,感觉自己对Binder的原理理解还是不太透彻,如果有什么不足,欢迎指正。

更多相关文章

  1. Android程序反编译的方法[已更新]
  2. android 开发技巧(5)--使 用 TextSwitcher 实现平滑过渡
  3. ListView的item点击事件及item中子view的点击事件冲突处理方法和
  4. Android学习之Adapter(适配器)源代码分析与观察者模式的运用(一)
  5. android多媒体框架之流媒体框架----base on jellybean(九)
  6. MQTT+ApolloServer实现Android的消息推送功能
  7. Android(安卓)在oncreate() 方法中调用 findViewById 返回 null
  8. Android简明开发教程十八:自定义对话框 Transform
  9. Android中的序列化和反序列化

随机推荐

  1. 5、控件系列之TOAST(吐司提示)的曾经、现在
  2. ADB WIFI DEBUG(ANDROID STUDIO)
  3. Android闹钟设置的解决方案
  4. 微软之鉴:Google不会将Android与Chrome OS
  5. Android系统移植与调试之------->如何修
  6. android中的键盘处理
  7. Google I/O 2014 New
  8. Android(安卓)应用程序之间数据共享—Con
  9. Android性能测试之卡顿ANR测试
  10. Android的Intent机制