在一个应用中,在正常的情况下,服务是不能被其他应用访问的,也就是跨进程通信(IPC),所以android采用了远程过程调用(RPC)来实现IPC,而android使用的是接口定义语言(IDL,)来公开服务接口供其他应用程序调用.android中的跨进程访问的服务称为AIDL服务.

首先,建立一个服务端android程序,通过AIDL提供服务

第一步:建立一个IMyService.aidl文件,自动生成一个IMyService.java接口,用于提供对外服务

IMyService.aidl源码:

//IMyService.aidlpackagecom.admin.zhangdengjie.aidl;//Declareanynon-defaulttypesherewithimportstatementsinterfaceIMyService{/***Demonstratessomebasictypesthatyoucanuseasparameters*andreturnvaluesinAIDL.*/StringgetValue();}

其中提供了一个简单的功能,返回一个字符串(getValue方法)

生成的IMyService.java源码(这个java文件是自动生成的,不要手动修改):

/**Thisfileisauto-generated.DONOTMODIFY.*Originalfile:/home/zhangdengjie/AndroidStudioProjects/MyApplication/aidl/src/main/aidl/com/admin/zhangdengjie/aidl/IMyService.aidl*/packagecom.admin.zhangdengjie.aidl;//importcom.admin.zhangdengjie.aidl.Product;//Declareanynon-defaulttypesherewithimportstatementspublicinterfaceIMyServiceextendsandroid.os.IInterface{/**Local-sideIPCimplementationstubclass.*/publicstaticabstractclassStubextendsandroid.os.Binderimplementscom.admin.zhangdengjie.aidl.IMyService{privatestaticfinaljava.lang.StringDESCRIPTOR="com.admin.zhangdengjie.aidl.IMyService";/**Constructthestubatattachittotheinterface.*/publicStub(){this.attachInterface(this,DESCRIPTOR);}/***CastanIBinderobjectintoancom.admin.zhangdengjie.aidl.IMyServiceinterface,*generatingaproxyifneeded.*/publicstaticcom.admin.zhangdengjie.aidl.IMyServiceasInterface(android.os.IBinderobj){if((obj==null)){returnnull;}android.os.IInterfaceiin=obj.queryLocalInterface(DESCRIPTOR);if(((iin!=null)&&(iininstanceofcom.admin.zhangdengjie.aidl.IMyService))){return((com.admin.zhangdengjie.aidl.IMyService)iin);}returnnewcom.admin.zhangdengjie.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.admin.zhangdengjie.aidl.IMyService{privateandroid.os.IBindermRemote;Proxy(android.os.IBinderremote){mRemote=remote;}@Overridepublicandroid.os.IBinderasBinder(){returnmRemote;}publicjava.lang.StringgetInterfaceDescriptor(){returnDESCRIPTOR;}/***Demonstratessomebasictypesthatyoucanuseasparameters*andreturnvaluesinAIDL.*/@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);}/***Demonstratessomebasictypesthatyoucanuseasparameters*andreturnvaluesinAIDL.*/publicjava.lang.StringgetValue()throwsandroid.os.RemoteException;}

第二部:创建一个MyService服务(android四大组件之一),在其中定义一个内部类MyServiceImpl,继承IMyService.Stub

MyService源码:

packagecom.admin.zhangdengjie.aidl.service;importandroid.app.Service;importandroid.content.Intent;importandroid.os.IBinder;importandroid.os.RemoteException;importcom.admin.zhangdengjie.aidl.IMyService;publicclassMyServiceextendsService{publicMyService(){}@OverridepublicIBinderonBind(Intentintent){//返回一个Binder对象,用于在客户端交互,客户端通过服务的回调方法onServiceConnected方法使用该Binder对象returnnewMyServiceImpl();}/***aidl实现类,MyServiceImpl继承IMyService.Stub,而IMyService.Stub继承android.os.Binder,所以MyServiceImpl可以作为IBinder对象返回*/publicclassMyServiceImplextendsIMyService.Stub{@OverridepublicStringgetValue()throwsRemoteException{return"这是一个示例";}}}

第三步:配置清单文件AndroidManifest.xml中Service的配置项

<serviceandroid:name=".service.MyService"android:enabled="true"android:exported="true"><!--com.admin.zhangdengjie.aidl.IMyService和客户端绑定服务的Intent对应,是其他应用调用该服务的服务ID--><intent-filter><actionandroid:name="com.admin.zhangdengjie.aidl.IMyService"/></intent-filter></service>

其次,建立调用服务的客户端:

第一步:将服务IMyService.aidl端生成的IMyService.java复制到客户端程序相同包下,如果没有对应的包名,新建之.

如,服务端IMyService包名:com.zdj.admin.zhangdengjie.aidl

客户端也需要有包名:com.zdj.admin.zhangdengjie.aidl,并且将复制过来的IMyService.java放在该包下

第二步:编写调用服务代码:

MainActivity.java源码:

packagecom.admin.zhangdengjie.aidlclient;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.util.Log;importandroid.view.View;importandroid.widget.Button;importandroid.widget.TextView;importcom.admin.zhangdengjie.aidl.IMyService;publicclassMainActivityextendsActivityimplementsView.OnClickListener{privateIMyServicemyService;privateButtonbtnInvokeAIDLService;privateButtonbtnBindAIDLService;privateTextViewtextView;privateServiceConnectionserviceConnection=newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){//获取服务对象,即服务端返回的service(IBinder)对象,跨进程myService=IMyService.Stub.asInterface(service);btnInvokeAIDLService.setEnabled(true);}@OverridepublicvoidonServiceDisconnected(ComponentNamename){}};@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btnInvokeAIDLService=(Button)findViewById(R.id.btnInvokeAIDLService);btnBindAIDLService=(Button)findViewById(R.id.btnBindAIDLService);textView=(TextView)findViewById(R.id.textView);btnInvokeAIDLService.setOnClickListener(this);btnBindAIDLService.setOnClickListener(this);}@OverridepublicvoidonClick(Viewv){switch(v.getId()){caseR.id.btnBindAIDLService:{//绑定AIDL服务,为了获取Service对象Log.e("MainActivity","绑定AIDL服务");bindService(newIntent("com.admin.zhangdengjie.aidl.IMyService"),serviceConnection,Context.BIND_AUTO_CREATE);break;}caseR.id.btnInvokeAIDLService:{try{textView.setText(myService.getValue());//调用服务端getValue方法}catch(RemoteExceptione){e.printStackTrace();}break;}}}}

最后,运行界面如图:

先点击绑定AIDL服务按钮,然后再调用AIDL服务按钮,即可看到远程服务端传递过来的字符串

总结:

1 应用的服务提供对外服务接口,是通过android的AIDL实现的

2 客户端需要获取服务端AIDL文件生成的java接口,且必须在同一包名下

3 客户端通过ServiceConnection的回调方法获取服务端返回的IBinder对象,从而实现通信

4 服务端的Service组件在被绑定的时候,返回adil文件生成的接口的内部类Stub的实现类,为IBinder的子类,该类实现的adil文件定义的方法是客户端和服务端Service组件之间通信的桥梁

更多相关文章

  1. Android系统服务-WindowManager
  2. Android基础之启动过程分析
  3. 开发android,我们需要哪些技能基础。
  4. Android启动过程深入解析
  5. Camera服务之--架构浅析
  6. android 启动过程及init.rc
  7. iOS Airplay--Airtunes音乐播放在Android盒子和手机上的实现 (终
  8. Android金毛狮王之Service
  9. Android系统启动流程浅析

随机推荐

  1. JAVA基础_Java IO流 控制台到记事本、记
  2. Java开发水吧点饮品系统(顶层父类对象做接
  3. java代码获知该方法被哪个类、哪个方法、
  4. 小女子想转学java,各位朋友能否给点建议
  5. java中的事件监听问题,如何将菜单项与组合
  6. java 调用 shell 得到返回值(二)
  7. android游戏开发学习 博客分类: android
  8. Java开发微信公众号(二)---开启开发者模式,
  9. linux环境下成功编译GDAL为JAVA库
  10. java项目中Classpath路径到底指的是哪里?