Android应用:Service开发实例(一)之AIDL和远程调用
2015-08-14 09:17
731 查看
在Android中, 每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢? 显然, Java中是不支持跨进程内存共享的。因此要传递对象, 需要把对象解析成操作系统能够理解的数据格式, 以达到跨界对象访问的目的。在JavaEE中,采用RMI通过序列化传递对象。在Android中, 则采用AIDL(Android Interface Definition Language:接口描述语言)方式实现。
AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC 机制和EJB所采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应 的对象。由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员
来说是透明的。
下边通过一个简单的例子来说明两个应用之间怎么使用aidl来通信。
一、服务器端开发
新建一个应用。
1、新建一个AIDL接口文件IMyAidlInterface.aidl
2、新建一个Service
二、客户端开发
新建另一个应用。
1、新建一个IMyAidlInterface.aidl文件,所在的包名必须和服务器端完全一致
2、在AndroidManifest.xml中添加服务
对象
三、运行效果
绑定服务
调用服务接口
AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC 机制和EJB所采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应 的对象。由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员
来说是透明的。
下边通过一个简单的例子来说明两个应用之间怎么使用aidl来通信。
一、服务器端开发
新建一个应用。
1、新建一个AIDL接口文件IMyAidlInterface.aidl
package com.dlq.myservice; interface IMyAidlInterface { void ServiceTest(); }这个AIDL在编译时会自动生成一个IMyAidlInterface.java文件
/* * This file is auto-generated. DO NOT MODIFY. * Original file: G:\\Android\\AndroidStudioProjects\\MyService\\app\\src\\main\\aidl\\com\\dlq\\myservice\\IMyAidlInterface.aidl */ package com.dlq.myservice; // Declare any non-default types here with import statements public interface IMyAidlInterface extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.dlq.myservice.IMyAidlInterface { private static final java.lang.String DESCRIPTOR = "com.dlq.myservice.IMyAidlInterface"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.dlq.myservice.IMyAidlInterface interface, * generating a proxy if needed. */ public static com.dlq.myservice.IMyAidlInterface asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.dlq.myservice.IMyAidlInterface))) { return ((com.dlq.myservice.IMyAidlInterface)iin); } return new com.dlq.myservice.IMyAidlInterface.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_ServiceTest: { data.enforceInterface(DESCRIPTOR); this.ServiceTest(); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.dlq.myservice.IMyAidlInterface { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public void ServiceTest() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_ServiceTest, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_ServiceTest = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public void ServiceTest() throws android.os.RemoteException; }
2、新建一个Service
package com.dlq.myservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class MyService extends Service { private static final String TAG = "MyService"; private MyServiceImpl mService; public MyService() { Log.d(TAG, "MyService"); } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "MyService onCreate"); //在onCreate中实例化一个service mService = new MyServiceImpl(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); Log.d(TAG, "MyService onStart"); } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "MyService onBind"); //在onBind中返回这个service的实例 return mService; } //实现aidl文件生成的接口(IMyAidlInterface),但并非直接实现接口,而是通过继承接口的Stub来实现(Stub抽象类内部实现了aidl接口),并且实现接口方法的代码。 private class MyServiceImpl extends IMyAidlInterface.Stub { @Override public void ServiceTest() throws RemoteException { Log.d(TAG, "MyService ServiceTest"); } } }3.在AndroidManifest.xml中添加服务
<service android:name=".MyService" android:enabled="true" android:exported="true" > </service>
二、客户端开发
新建另一个应用。
1、新建一个IMyAidlInterface.aidl文件,所在的包名必须和服务器端完全一致
2、在AndroidManifest.xml中添加服务
<service android:name="com.dlq.myservice.IMyAidlInterface" android:enabled="true" android:exported="true" > </service>3、在Activity中的按钮中添加代码,通过bindservice启动服务
Intent intent = new Intent(); //这里通过包名和类名启动服务,也可以通过Action来启动 intent.setClassName("com.dlq.myservice","com.dlq.myservice.MyService"); //android5.0以后必须显示启动服务,intent中需要添加包名 intent.setPackage(getPackageName()); bindService(intent, con, BIND_AUTO_CREATE);4、客户端绑定service时在ServiceConnection.onServiceConnected获取onBind返回的IBinder
对象
private IMyAidlInterface mService; ServiceConnection con = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = IMyAidlInterface.Stub.asInterface(service); Log.d(TAG, "MyClient mService="+mService); } @Override public void onServiceDisconnected(ComponentName name) { } };5、在另一个按钮中调用Service中实现的接口
try { mService.ServiceTest(); } catch (RemoteException e) { e.printStackTrace(); }6、使用unbindService解除绑定
this.unbindService(con);
三、运行效果
绑定服务
08-14 20:20:25.222 6831-6831/com.dlq.myservice D/MyService﹕ MyService 08-14 20:20:25.222 6831-6831/com.dlq.myservice D/MyService﹕ MyService onCreate 08-14 20:20:25.223 6831-6831/com.dlq.myservice D/MyService﹕ MyService onBind
调用服务接口
08-14 20:20:28.662 6831-6847/com.dlq.myservice D/MyService﹕ MyService ServiceTest
相关文章推荐
- Android统计图表MPAndroidChart
- Android 讲sqlite数据库打包同apk一同发布
- 【转】GitHub 优秀的 Android 开源项目
- android studio 64位手机+Fresco引起的在arm64位机器上找不到对应的so库
- Android列表数据动态改变
- Android 命名规范 (提高代码可以读性)
- android4.0 锁屏实现(转)
- android 代码设置、打开wifi热点及热点的连接(转)
- android tv 全屏幕垂直画
- Android异步任务AsyncTask实现方式
- Android 主要目录及文件简介
- Android drawable selector 设置无效
- AndroidManifest.xml文件解析
- android引用外部数据库到应用中
- Android存储子系统
- Android 的odex的文件反编译
- Android的源码的多产品分支
- Android的代码同步repo
- Android 查看内存的方法
- Android的Framework分析---5 ActivityManager分析