ImageVerifierCode 换一换
格式:DOCX , 页数:13 ,大小:49.93KB ,
资源ID:7269851      下载积分:2 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7269851.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(AIDLAndroid中的远程接口调用RPC.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

AIDLAndroid中的远程接口调用RPC.docx

1、AIDL Android中的远程接口调用RPC远程过程调用Android拥有轻量级的远程调用机制 (RPC) 方法在本地调用,在远程执行(在其它进程中),结果返回给调用者。这意味着将方法调用及其附带的数据分解为操作系统可以理解的形式,将其由本地进程和地址空间传送到远程进程和地址空间中,在远程重新装配并执行该调用。返回值沿着相反的方向传递。Android提供了实现该机制的所有代码,因此你只需要关注于如何定义和实现该RPC接口本身。RPC接口只能包含方法。所有的方法都是同步执行的(本地方法被阻断,直到远程方法结束),即使没有返回值。简而言之,该机制的流程如下:你由使用简单的IDL(接口定义语言)定

2、义要实现的RPC接口。根据接口的定义, aidl 工具生成本地和远程进程必要的Java接口的定义。它包含下图所示的两个内部类:内部类中包含管理你用IDL生成的远程过程调用需要的所有代码。两个内部类都实现了IBinder 接口。其中一个在本地由系统内部使用,写代码时可以忽略它。另一个叫做 Stub,扩展自Binder 类。作为对执行IPC调用的内部代码补充,它包含你在RPC接口中声明的方法。象图中说明的那样,你应该继承Stub来实现这些方法。一般远程过程由服务来管理(因为服务可以通知系统关于进程和它连接的其它进程的信息)。它既有aidl。服务的客户端只有由aidl生成的接口文件。接下来是服务和其

3、客户端是如何建立连接的:服务的客户端(为位于本地)应该实现onServiceConnected() 和onServiceDisconnected() 方法,这样它们就可以在成功与远程服务建立或断开连接后收到消息。它们应该调用bindService() 来设置连接。 服务的onBind() 方法应该被实现用作根据收到的意图(传入bindService()的意图),决定接受或拒绝连接。 如果连接被接受,它返回一个Stub的子类。如果服务接受了连接,Android调用客户端的onServiceConnected() 方法并传入一个IBinder对象,由服务管理的Stub子类的代理。通过该代理,客户端

4、可以调用远程服务。 上述简单的描述忽略了一些RPC机制的细节。更多信息参见用AIDL设计远程接口和IBinder 类的描述。在Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service. 在不同的进程中, 怎样传递对象呢? 显然, Java中不允许跨进程内存共享. 因此传递对象, 只能把对象拆分成操作系统能理解的简单形式, 以达到跨界对象访问的目的. 在J2EE中,采用RMI的方式, 可以通过序列化传递对象. 在Android中, 则采用AIDL的方式. 理论上AIDL可以传递Bundle,实际上做起来却比较麻烦.AIDL(AndRoid接口描述语言)

5、是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象.AIDL的IPC的机制和COM或CORBA类似, 是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相关类.; 2. 调用aidl产生的class.具体实现步骤如下:1、创建AIDL

6、文件, 在这个文件里面定义接口, 该接口定义了可供客户端访问的方法和属性。 如: ITaskBinder.adilpackage com.cmcc.demo;import com.cmcc.demo.ITaskCallback;interface ITaskBinder boolean isTaskRunning(); void stopRunningTask(); void registerCallback(ITaskCallback cb); void unregisterCallback(ITaskCallback cb);其中: ITaskCallback在文件ITaskCallbac

7、k.aidl中定义:package com.cmcc.demo;interface ITaskCallback void actionPerformed(int actionId);注意: 理论上, 参数可以传递基本数据类型和String, 还有就是Bundle的派生类, 不过在Eclipse中,目前的ADT不支持Bundle做为参数, 据说用Ant编译可以, 我没做尝试.2、编译AIDL文件, 用Ant的话, 可能需要手动, 使用Eclipse plugin的话,可以根据adil文件自动生产java文件并编译, 不需要人为介入.3、在Java文件中, 实现AIDL中定义的接口. 编译器会根据

8、AIDL接口, 产生一个JAVA接口。这个接口有一个名为Stub的内部抽象类,它继承扩展了接口并实现了远程调用需要的几个方法。接下来就需要自己去实现自定义的几个接口了.ITaskBinder.aidl中接口的实现, 在MyService.java中接口以内嵌类的方式实现:private final ITaskBinder.Stub mBinder = new ITaskBinder.Stub() public void stopRunningTask() /TODO public boolean isTaskRunning() /TODO return false; public void r

9、egisterCallback(ITaskCallback cb) if (cb != null) mCallbacks.register(cb); public void unregisterCallback(ITaskCallback cb) if (cb != null) mCallbacks.unregister(cb); ;在MyActivity.java中ITaskCallback.aidl接口实现:private ITaskCallback mCallback = new ITaskCallback.Stub() public void actionPerformed(int i

10、d) /TODO printf(callback id= + id); ;4、向客户端提供接口ITaskBinder, 如果写的是service,扩展该Service并重载onBind ()方法来返回一个实现上述接口的类的实例。这个地方返回的mBinder,就是上面通过内嵌了定义的那个. (MyService.java) public IBinder onBind(Intent t) printf(service on bind); return mBinder;在Activity中, 可以通过Binder定义的接口, 来进行远程调用.5、在服务器端回调客户端的函数. 前提是当客户端获取的IB

11、inder接口的时候,要去注册回调函数, 只有这样, 服务器端才知道该调用那些函数在:MyService.java中: void callback(int val) final int N = mCallbacks.beginBroadcast(); for (int i=0; iN; i+) try mCallbacks.getBroadcastItem(i).actionPerformed(val); catch (RemoteException e) / The RemoteCallbackList will take care of removing / the dead object

12、 for us. mCallbacks.finishBroadcast();AIDL的创建方法:AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。 由于远程调用的需要, 这些参数和返回值并不是任何类型.下面是些AIDL支持的数据类型:1. 不需要import声明的简单Java编程语言类型(int,boolean等)2. String, CharSequence不需要特殊声明3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型.(另外: 我没尝试Parcelables, 在Ecl

13、ipse+ADT下编译不过, 或许以后会有所支持).下面是AIDL语法:/ 文件名: SomeClass.aidl/ 文件可以有注释, 跟java的一样/ 在package以前的注释, 将会被忽略./ 函数和变量以前的注释, 都会被加入到生产java代码中.package com.cmcc.demo;/ import 引入语句import com.cmcc.demo.ITaskCallback;interface ITaskBinder /函数跟java一样, 可以有0到多个参数 ,可以有一个返回值 boolean isTaskRunning(); void stopRunningTask()

14、; /参数可以是另外的一个aidl定义的接口 void registerCallback(ITaskCallback cb);void unregisterCallback(ITaskCallback cb);/参数可以是String, 可以用in表入输入类型, out表示输出类型.int getCustomerList(in String branch, out String customerList);实现接口时有几个原则:.抛出的异常不要返回给调用者. 跨进程抛异常处理是不可取的.IPC调用是同步的。如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的

15、主线程中调用。也就是IPC调用会挂起应用程序导致界面失去响应. 这种情况应该考虑单起一个线程来处理.不能在AIDL接口中声明静态属性。IPC的调用步骤:1. 声明一个接口类型的变量,该接口类型在.aidl文件中定义。2. 实现ServiceConnection。3. 调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递.4. 在ServiceConnection.onServiceConnected()实现中,你会接收一个IBinder实例(被调用的Service). 调用 YourInterfaceName.Stub.as

16、Interface(IBinder)service)将参数转换为YourInterface类型。5. 调用接口中定义的方法。你总要检测到DeadObjectException异常,该异常在连接断开时被抛出。它只会被远程方法抛出。6. 断开连接,调用接口实例中的ApplicationContext.unbindService()下面是整个程序:1. ITaskCallback.aidlpackage com.cmcc.demo;interface ITaskCallback void actionPerformed(int actionId);2. ITaskBinder.aidlpackage

17、 com.cmcc.demo;import com.cmcc.demo.ITaskCallback;interface ITaskBinder boolean isTaskRunning(); void stopRunningTask(); void registerCallback(ITaskCallback cb); void unregisterCallback(ITaskCallback cb);3. MyService.javapackage com.cmcc.demo;import android.app.Service;import android.content.Intent;

18、import android.os.IBinder;import android.os.RemoteCallbackList;import android.os.RemoteException;import android.util.Log;public class MyService extends Service Override public void onCreate() printf(service create); Override public void onStart(Intent intent, int startId) printf(service start id= +

19、startId); callback(startId); Override public IBinder onBind(Intent t) printf(service on bind); return mBinder; Override public void onDestroy() printf(service on destroy); super.onDestroy(); Override public boolean onUnbind(Intent intent) printf(service on unbind); return super.onUnbind(intent); pub

20、lic void onRebind(Intent intent) printf(service on rebind); super.onRebind(intent); private void printf(String str) Log.e(TAG, #- + str + -); void callback(int val) final int N = mCallbacks.beginBroadcast(); for (int i=0; iN; i+) try mCallbacks.getBroadcastItem(i).actionPerformed(val); catch (Remote

21、Exception e) / The RemoteCallbackList will take care of removing / the dead object for us. mCallbacks.finishBroadcast(); private final ITaskBinder.Stub mBinder = new ITaskBinder.Stub() public void stopRunningTask() public boolean isTaskRunning() return false; public void registerCallback(ITaskCallba

22、ck cb) if (cb != null) mCallbacks.register(cb); public void unregisterCallback(ITaskCallback cb) if (cb != null) mCallbacks.unregister(cb); ; final RemoteCallbackList mCallbacks = new RemoteCallbackList();4. MyActivity.javapackage com.cmcc.demo;import android.app.Activity;import android.content.Comp

23、onentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.graphics.Color;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;import android.view.View;import android.view.View

24、Group;import android.view.View.OnClickListener;import android.widget.AbsoluteLayout;import android.widget.Button;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.TextView;import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;im

25、port java.io.FileReader;import java.io.PrintWriter;public class MyActivity extends Activity private Button btnOk; private Button btnCancel; Override public void onCreate(Bundle icicle) super.onCreate(icicle); setContentView(R.layout.test_service); btnOk = (Button)findViewById(R.id.btn_ok); btnCancel

26、 = (Button)findViewById(R.id.btn_cancel); btnOk.setText(Start Service); btnCancel.setTag(Stop Service); btnOk.setOnClickListener(new OnClickListener() public void onClick(View v) onOkClick(); ); btnCancel.setOnClickListener(new OnClickListener() public void onClick(View v) onCancelClick(); ); void onOkClick() Bundle args = new Bundle(); Intent intent = new Intent(this, MyService.class); intent.putExtras(args); /printf(send intent to start); /startService(intent); bindService(intent, mConnection, Context.BIND_AUTO_CREA

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1