使用AIDL实现进程通信
2014-04-23 14:36
288 查看
使用AIDL和远程服务实现进程通信
在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然,java中是不支持垮进程内存共享的。因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到垮界对象访问的目的。在java ee中,采用RMI通过序列化传递对象。在android中,采用AIDL(Android Interface Definition Language:j接口定义语言)方式实现。
AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC机制和EJB所采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议信息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。
一、服务端的实现:
1、写一个AIDL文件:
2、开发工具自动生成一个接口:
3、service的代码:
4、配置service的action:
这里遇到一个问题,笔者写错了manifest 的 package,然后安装到设备上,后来改正确路劲了,还是报这个错误:java lang runtimeexception unable to instantiate service。直至在设备上删除这个服务,再安装它,重新启动设备,这个错误才消失。
二、客户端的实现
1、把服务端的aidl 文件(包括路劲)复制到 客户端;
2、客户端的代码实现:
在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然,java中是不支持垮进程内存共享的。因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到垮界对象访问的目的。在java ee中,采用RMI通过序列化传递对象。在android中,采用AIDL(Android Interface Definition Language:j接口定义语言)方式实现。
AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC机制和EJB所采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议信息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。
一、服务端的实现:
1、写一个AIDL文件:
package cn.license.android; interface StudentRemote { String QueryStudent(int studentNo); }
2、开发工具自动生成一个接口:
/* * This file is auto-generated. DO NOT MODIFY. * Original file: C:\\Users\\Administrator\\workspace\\StudentRemoteService\\src\\cn\\license\\android\\StudentRemote.aidl */ package cn.license.android; public interface StudentRemote extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements cn.license.android.StudentRemote { private static final java.lang.String DESCRIPTOR = "cn.license.android.StudentRemote"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an cn.license.android.StudentRemote interface, * generating a proxy if needed. */ public static cn.license.android.StudentRemote asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof cn.license.android.StudentRemote))) { return ((cn.license.android.StudentRemote)iin); } return new cn.license.android.StudentRemote.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_QueryStudent: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); java.lang.String _result = this.QueryStudent(_arg0); reply.writeNoException(); reply.writeString(_result); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements cn.license.android.StudentRemote { 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 java.lang.String QueryStudent(int studentNo) throws android.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); _data.writeInt(studentNo); mRemote.transact(Stub.TRANSACTION_QueryStudent, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_QueryStudent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public java.lang.String QueryStudent(int studentNo) throws android.os.RemoteException; }
3、service的代码:
public class StudentRemoteService extends Service { private String[] students={"name1","name 2","name 3"}; private IBinder binder = new StudentRemoteBinder(); @Override public IBinder onBind(Intent intent) { return binder; } private String QueryStudentName(int studentNo){ if(studentNo>0 && studentNo<=students.length){ return students[studentNo-1]; } return null; }
//继承开发工具自动生成的接口里面的一个类 private final class StudentRemoteBinder extends StudentRemote.Stub{ @Override public String QueryStudent(int studentNo) throws RemoteException { return QueryStudentName(studentNo); } } }
4、配置service的action:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.license.android" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <service android:name=".StudentRemoteService"> <intent-filter> <action android:name="cn.license.studentQuery"/> </intent-filter> </service> </application> </manifest>
这里遇到一个问题,笔者写错了manifest 的 package,然后安装到设备上,后来改正确路劲了,还是报这个错误:java lang runtimeexception unable to instantiate service。直至在设备上删除这个服务,再安装它,重新启动设备,这个错误才消失。
二、客户端的实现
1、把服务端的aidl 文件(包括路劲)复制到 客户端;
2、客户端的代码实现:
public class MainActivity extends Activity { private ServiceConnection conn = new StudentServiceConnection(); //private IStudentBinder studentService; private StudentRemote studentRemote; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //显示意图 //Intent service = new Intent(this,StudentService.class); //隐式意图,此处用来激活远程服务 Intent service = new Intent("cn.license.studentQuery"); bindService(service, conn, BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); unbindService(conn); } public void query(View v){ EditText studentNoText = (EditText)this.findViewById(R.id.studentNo); int studentNo = Integer.valueOf(studentNoText.getText().toString()); String studentName=""; try { studentName = studentRemote.QueryStudent(studentNo); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); }//studentService.QueryName(studentNo); TextView studentNameText = (TextView) this.findViewById(R.id.studentName); studentNameText.setText(studentName); } private class StudentServiceConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { //本地 //studentService = (IStudentBinder)service; //远程 aidl studentRemote = StudentRemote.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { //studentService=null; studentRemote = null; } } }
相关文章推荐
- Android笔记 使用AIDL和远程服务实现进程通信
- 使用AIDL方式启动Service 实现跨进程通信
- 使用AIDL实现Android的跨进程通信
- Android使用AIDL和远程服务实现进程通信
- 使用AIDL实现进程通信
- Adroid 使用AIDL和远程服务实现进程通信
- AndroidStudio中使用AIDL实现进程间通信
- Android中的跨进程通信的实现——远程调用过程和aidl
- android跨进程通信(IPC):使用AIDL
- openwrt中使用ubus实现进程通信
- Android Binder机制实现进程间数据交换(不使用aidl实现)
- Android中AIDL实现(跨进程通信)
- Android中不使用AIDL实现Service的远程调用
- 使用AIDL实现进程间的通信
- Android:使用AIDL实现进程间通讯
- android studio 中aidl文件的使用并且实现跨进程的通信
- 使用AIDL实现IPC
- Android进阶:AIDL实现IPC使用详解
- 使用AIDL实现进程间的通信
- Android实现进程间通信aidl的使用