Android Service总结06 之AIDL
2016-09-21 11:23
232 查看
1AIDL介绍
AIDL,即AndroidInterfaceDefinitionLanguage。
Android使用AIDL来完成进程间通信(IPC),并且一般在服务需要接受不同应用多线程的请求时才需要使用AIDL;如果是同一个应用内的请求使用Binder实现即可;如果只是应用间通信而不是多线程处理的话使用Messenger,当然这两种情况也可以使用AIDL。本地进程和远程进程使用AIDL有所不同,本地进程内调用时会都在调用的线程内执行,远程进程使用是通过Service进程内一个由系统维护的线程池发出调用,所以可能是未知线程同时调用,需要注意线程安全问题。
2AIDL示例
创建AIDL服务的步骤: (01)创建.aidl文件。.aidl是接口文件,它定义了服务所能提供的功能。 (02)实现.aidl所定义的接口。 (03)将接口开放给其它应用程序。
2.1创建.aidl文件
(01)打开eclipse,新建工程”AIDLServiceImpl”,然后在工程的“com.text”包下创建“MyAIDLInterface.aidl”文件。
如下图:
(02)编辑“MyAIDLInterface.aidl”,提供doubleValue(intval)和halfValue(intvalue)服务。
“MyAIDLInterface.aidl”代码如下:
packagecom.test; interfaceMyAIDLInterface{ voiddoubleValue(intval); voidhalfValue(intval); }
(03)编译工程,在“gen”目录下会自动生成与“MyAIDLInterface.aidl”对应的“MyAIDLInterface.java”文件。
如下图:
“MyAIDLInterface.java”代码如下:
/* *Thisfileisauto-generated.DONOTMODIFY. *Originalfile:F:\\workout\\android\\AIDLServiceImpl\\src\\com\\test\\MyAIDLInterface.aidl */ packagecom.test; publicinterfaceMyAIDLInterfaceextendsandroid.os.IInterface { /**Local-sideIPCimplementationstubclass.*/ publicstaticabstractclassStubextendsandroid.os.Binderimplementscom.test.MyAIDLInterface { privatestaticfinaljava.lang.StringDESCRIPTOR="com.test.MyAIDLInterface"; /**Constructthestubatattachittotheinterface.*/ publicStub() { this.attachInterface(this,DESCRIPTOR); } /** *CastanIBinderobjectintoancom.test.MyAIDLInterfaceinterface, *generatingaproxyifneeded. */ publicstaticcom.test.MyAIDLInterfaceasInterface(android.os.IBinderobj) { if((obj==null)){ returnnull; } android.os.IInterfaceiin=(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR); if(((iin!=null)&&(iininstanceofcom.test.MyAIDLInterface))){ return((com.test.MyAIDLInterface)iin); } returnnewcom.test.MyAIDLInterface.Stub.Proxy(obj); } publicandroid.os.IBinderasBinder() { returnthis; } @OverridepublicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)throwsandroid.os.RemoteException { switch(code) { caseINTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); returntrue; } caseTRANSACTION_doubleValue: { data.enforceInterface(DESCRIPTOR); int_arg0; _arg0=data.readInt(); this.doubleValue(_arg0); reply.writeNoException(); returntrue; } caseTRANSACTION_halfValue: { data.enforceInterface(DESCRIPTOR); int_arg0; _arg0=data.readInt(); this.halfValue(_arg0); reply.writeNoException(); returntrue; } } returnsuper.onTransact(code,data,reply,flags); } privatestaticclassProxyimplementscom.test.MyAIDLInterface { privateandroid.os.IBindermRemote; Proxy(android.os.IBinderremote) { mRemote=remote; } publicandroid.os.IBinderasBinder() { returnmRemote; } publicjava.lang.StringgetInterfaceDescriptor() { returnDESCRIPTOR; } publicvoiddoubleValue(intval)throwsandroid.os.RemoteException { android.os.Parcel_data=android.os.Parcel.obtain(); android.os.Parcel_reply=android.os.Parcel.obtain(); try{ _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(val); mRemote.transact(Stub.TRANSACTION_doubleValue,_data,_reply,0); _reply.readException(); } finally{ _reply.recycle(); _data.recycle(); } } publicvoidhalfValue(intval)throwsandroid.os.RemoteException { android.os.Parcel_data=android.os.Parcel.obtain(); android.os.Parcel_reply=android.os.Parcel.obtain(); try{ _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(val); mRemote.transact(Stub.TRANSACTION_halfValue,_data,_reply,0); _reply.readException(); } finally{ _reply.recycle(); _data.recycle(); } } } staticfinalintTRANSACTION_doubleValue=(android.os.IBinder.FIRST_CALL_TRANSACTION+0); staticfinalintTRANSACTION_halfValue=(android.os.IBinder.FIRST_CALL_TRANSACTION+1); } publicvoiddoubleValue(intval)throwsandroid.os.RemoteException; publicvoidhalfValue(intval)throwsandroid.os.RemoteException; }
2.2实现.aidl所定义的接口
(04)在“com.test”包下新建文件MyAIDLService.java,并实现doubleValue(intval)和halfValue(intvalue)接口。
如下图:
MyAIDLService.java的代码如下:
packagecom.test;importandroid.app.Service;importandroid.content.Intent;importandroid.os.IBinder;importandroid.os.RemoteException;importandroid.util.Log;publicclassMyAIDLServiceextendsService{privatestaticfinalStringTAG="skywang-->MyAIDLService";privateMyAIDLInterface.StubmyBinder=newMyAIDLInterface.Stub(){@OverridepublicvoidhalfValue(intval)throwsRemoteException{Log.d(TAG,"halfValueval="+val/2);}@OverridepublicvoiddoubleValue(intval)throwsRemoteException{Log.d(TAG,"doubleValueval="+val*2);}};@OverridepublicvoidonCreate(){super.onCreate();}@OverridepublicvoidonDestroy(){super.onDestroy();}@OverridepublicIBinderonBind(Intentintent){returnmyBinder;}}
(05)定义aidl对应的manifestmanifest内容如下:
<manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.test"android:versionCode="1"android:versionName="1.0"><uses-sdkandroid:minSdkVersion="9"android:targetSdkVersion="17"/><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme"><serviceandroid:name=".MyAIDLService"android:process=":remote"><intent-filter><actionandroid:name="com.test.MY_AIDL_SERVICE"/></intent-filter></service></application></manifest>
至此,我们已经完成了.aidl服务的定义和实现。
2.3将接口开放给其它应用程序
(06)新建一个工程“AIDLServiceTest”,然后在工程的“com.skywang”包下创建AIDLServiceTest.java;(07)然后,将MyAIDLInterface.aidl文件拷贝到AIDLServiceTest工程的“com.test”包下。
如下图:
注意:.aidl所在的包名,必须和定义它的包名一样!(即MyAIDLInterface.aidl所在的定义它的工程的包为com.test;那么,调用MyAIDLInterface.aidl的程序,也必须把MyAIDLInterface.aidl放在com.test包下面)(08)AIDLServiceTest.java首先必须实现ServiceConnection接口。
实现ServiceConnection接口的原因是:我们在后面调用.aidl服务的时候,必须通过bindService()去绑定服务;而bindService()需要用到ServiceConnection对象。实现ServiceConnection很简单,只需要实现两个接口:onServiceConnected——连上服务的回调函数。一般在此函数中,获取服务对象。onServiceDisconnected——断开服务的回调函数。可以直接返回null。
ServiceConnection的实现代码如下:
privateMyAIDLInterfacemBinder=null;privateServiceConnectionmConnection=newServiceConnection(){@OverridepublicvoidonServiceDisconnected(ComponentNamename){mBinder=null;}@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){Log.d(TAG,"Serviceconnected!");mBinder=MyAIDLInterface.Stub.asInterface(service);}};
(09)开始访问服务之前,我们要先通过bindService()绑定服务;使用完毕之后,通过unbindService()断开服务。AIDLServiceTest.java代码如下:
packagecom.skywang;importandroid.app.Activity;importandroid.os.Bundle;importandroid.os.IBinder;importandroid.os.RemoteException;importandroid.util.Log;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.content.ComponentName;importandroid.content.Intent;importandroid.content.Context;importandroid.content.ServiceConnection;importcom.test.MyAIDLInterface;publicclassAIDLServiceTestextendsActivity{privatestaticfinalStringTAG="skywang-->AIDLServiceTest";privateButtonmStart=null;privateButtonmHalf=null;privateButtonmDouble=null;privateButtonmEnd=null;privateMyAIDLInterfacemBinder=null;privateServiceConnectionmConnection=newServiceConnection(){@OverridepublicvoidonServiceDisconnected(ComponentNamename){mBinder=null;}@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){Log.d(TAG,"Serviceconnected!");mBinder=MyAIDLInterface.Stub.asInterface(service);}};@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.aidlservice_test);mStart=(Button)findViewById(R.id.btStart);mStart.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewarg0){Log.d(TAG,"clickstartbutton");Intentintent=newIntent("com.test.MY_AIDL_SERVICE");booleanresult=bindService(intent,mConnection,Context.BIND_AUTO_CREATE);if(!result){mBinder=null;}}});mHalf=(Button)findViewById(R.id.btHalf);mHalf.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewarg0){Log.d(TAG,"clickhalfbutton");try{if(mBinder!=null){mBinder.halfValue(10);}}catch(RemoteExceptione){e.printStackTrace();}}});mDouble=(Button)findViewById(R.id.btDouble);mDouble.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewarg0){Log.d(TAG,"clickdoublebutton");try{if(mBinder!=null){mBinder.doubleValue(10);}}catch(RemoteExceptione){e.printStackTrace();}}});mEnd=(Button)findViewById(R.id.btEnd);mEnd.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewarg0){Log.d(TAG,"clickendbutton");if(mBinder!=null){unbindService(mConnection);mBinder=null;}}});}}3示例演示
程序运行效果图:
点击“Start”按钮,Logcat如下:DEBUG/skywang-->AIDLServiceTest(276):clickhalfbuttonDEBUG/skywang-->AIDLServiceTest(276):Serviceconnected!点击“Half”按钮,Logcat如下:DEBUG/skywang-->AIDLServiceTest(276):clickhalfbuttonDEBUG/skywang-->MyAIDLService(285):halfValueval=5点击“Double”按钮,Logcat如下:DEBUG/skywang-->AIDLServiceTest(276):clickdoublebuttonDEBUG/skywang-->MyAIDLService(285):doubleValueval=20点击“End”按钮,Logcat如下:DEBUG/skywang-->AIDLServiceTest(276):clickendbutton
4参考文献
1.AndroidAPI文档:http://developer.android.com/guide/components/aidl.html
2.AndroidAIDL使用详解:http://blog.csdn.net/stonecao/article/details/6425019
点击下载:源代码
相关文章推荐
- Android Service总结06 之AIDL
- android之Service介绍之二 AIDL
- Android Service学习之AIDL, Parcelable和远程服务 推荐
- Android Service学习之AIDL, Parcelable和远程服务
- Android Service学习之AIDL, Parcelable和远程服务
- android中service和aidl详细整理
- gps和android service和pseudo terminal学习总结
- Android AIDL和远程Service调用(一)
- Android 中的 Service 全面总结
- Android 中的 Service 全面总结
- Android中RemoteService的使用详解(Aidl、IPC机制)
- android中service和aidl详细整理
- Android Service学习之AIDL, Parcelable和远程服务
- Android Service学习之AIDL, Parcelable和远程服务
- Android 中的 Service 全面总结
- android之Service介绍之三 AIDL与传递对象
- Android Service学习之AIDL, Parcelable和远程服务
- Android 中的 Service 全面总结
- Android 四大组件之(2)Service实现原理以及AIDL语言的使用详解
- Android Service学习之AIDL, Parcelable和远程服务