大家好,好久不见,今天要给大家分享的是android aidl的使用。在Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service. 在不同的进程中, 怎样传递对象呢? 显然, Java中不允许跨进程内存共享. 因此传递对象, 只能把对象拆分成操作系统能理解的简单形式, 以达到跨界对象访问的目的. 在J2EE中,采用RMI的方式, 可以通过序列化传递对象. 在Android中, 则采用AIDL的方式. 理论上AIDL可以传递Bundle,实际上做起来却比较麻烦.


AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象.

AIDL的IPC的机制和COM或CORBA类似, 是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相关类.; 2. 调用aidl产生的class.

今天的两个实例用到两个Android工程,一个是AIDL的服务端另一个是客户端。

服务端的实现步骤:

首先看一下服务端,工程目录如下:

Android 中的AIDL_第1张图片

首先创建IaidlServerService.aidl文件,代码如下(一个简单方法,另一个返回对象方法),当我们点击保存时会在gen目录下生成对应的java文件,如上图红色部分:

[java] view plain copy
  1. packagecom.chapter8.aidl;
  2. importcom.chapter8.aidl.Book;
  3. interfaceIAIDLServerService{
  4. StringsayHello();
  5. BookgetBook();
  6. }

第二步:因为这个接口里有传递对象,所以对象要特殊处理一下,这里继承了Parcelable,Book.java代码如下:

如果大家不明的地方,请参见,下面连接的文章:

Android高手进阶教程(十七)之---Android中Intent传递对象的两种方法(Serializable,Parcelable)!

[java] view plain copy
  1. packagecom.chapter8.aidl;
  2. importandroid.os.Parcel;
  3. importandroid.os.Parcelable;
  4. publicclassBookimplementsParcelable{
  5. privateStringbookName;
  6. privateintbookPrice;
  7. publicBook(){
  8. }
  9. publicBook(Parcelparcel){
  10. bookName=parcel.readString();
  11. bookPrice=parcel.readInt();
  12. }
  13. publicStringgetBookName(){
  14. returnbookName;
  15. }
  16. publicvoidsetBookName(StringbookName){
  17. this.bookName=bookName;
  18. }
  19. publicintgetBookPrice(){
  20. returnbookPrice;
  21. }
  22. publicvoidsetBookPrice(intbookPrice){
  23. this.bookPrice=bookPrice;
  24. }
  25. publicintdescribeContents(){
  26. return0;
  27. }
  28. publicvoidwriteToParcel(Parcelparcel,intflags){
  29. parcel.writeString(bookName);
  30. parcel.writeInt(bookPrice);
  31. }
  32. publicstaticfinalParcelable.Creator<Book>CREATOR=newCreator<Book>(){
  33. publicBookcreateFromParcel(Parcelsource){
  34. returnnewBook(source);
  35. }
  36. publicBook[]newArray(intsize){
  37. returnnewBook[size];
  38. }
  39. };
  40. }

第三步:写一个与Book类对应的aidl,命名为Book.aidl,代码非常简单,代码如下:

[java] view plain copy
  1. parcelableBook;

第四步:新建一个名为AidlServerService的Service.代码如下:

[java] view plain copy
  1. packagecom.chapter8.aidl;
  2. importcom.chapter8.aidl.IAIDLServerService.Stub;
  3. importcom.chapter8.aidl.IAIDLServerService;
  4. importandroid.app.Service;
  5. importandroid.content.Intent;
  6. importandroid.os.IBinder;
  7. importandroid.os.RemoteException;
  8. publicclassAidlServerServiceextendsService{
  9. @Override
  10. publicIBinderonBind(Intentintent){
  11. returnmBinder;
  12. }
  13. /**
  14. *在AIDL文件中定义的接口实现。
  15. */
  16. privateIAIDLServerService.StubmBinder=newStub(){
  17. publicStringsayHello()throwsRemoteException{
  18. return"Hello";
  19. }
  20. publicBookgetBook()throwsRemoteException{
  21. BookmBook=newBook();
  22. mBook.setBookName("Android应用开发");
  23. mBook.setBookPrice(50);
  24. returnmBook;
  25. }
  26. };
  27. }

第五步:在AndroidManifest.xml注册Service,代码如下:

[java] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.chapter8.aidl"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  7. <activityandroid:name="AidlServerActivity"
  8. android:label="@string/app_name">
  9. <intent-filter>
  10. <actionandroid:name="android.intent.action.MAIN"/>
  11. <categoryandroid:name="android.intent.category.LAUNCHER"/>
  12. </intent-filter>
  13. </activity>
  14. <serviceandroid:name="AidlServerService"
  15. android:process=":remote">
  16. <intent-filter>
  17. <actionandroid:name="com.chapter8.aidl.IAIDLServerService"></action>
  18. </intent-filter>
  19. </service>
  20. </application>
  21. </manifest>

第六步:运行服务端工程,到设备上,好让客户端调用,服务端的Activity什么都没做.效果如下:

Android 中的AIDL_第2张图片

客户端的具体实现步骤:


第一步:新建客户端工程,目录结构如下:

Android 中的AIDL_第3张图片

第二步:引入Aidl文件以及用到的类,如上面的com.chapter8.aidl包。直接从服务端里代码copy过来就OK.

第三步:修改main.xml布局文件,增加一个按钮,代码如下:

[java] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TextView
  8. android:id="@+id/textview"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:text="@string/hello"
  12. />
  13. <Button
  14. android:id="@+id/button"
  15. android:layout_width="fill_parent"
  16. android:layout_height="wrap_content"
  17. android:text="调用AIDL服务"
  18. />
  19. </LinearLayout>

第四步:修改AidlClientActivity.java代码如下:

[java] view plain copy
  1. packagecom.chapter8.aidlclient;
  2. importcom.chapter8.aidl.IAIDLServerService;
  3. importandroid.app.Activity;
  4. importandroid.content.ComponentName;
  5. importandroid.content.Intent;
  6. importandroid.content.ServiceConnection;
  7. importandroid.os.Bundle;
  8. importandroid.os.IBinder;
  9. importandroid.os.RemoteException;
  10. importandroid.view.View;
  11. importandroid.view.View.OnClickListener;
  12. importandroid.widget.Button;
  13. importandroid.widget.TextView;
  14. publicclassAidlClientActivityextendsActivity{
  15. privateTextViewmTextView;
  16. privateButtonmButton;
  17. privateIAIDLServerServicemIaidlServerService=null;
  18. privateServiceConnectionmConnection=newServiceConnection(){
  19. publicvoidonServiceDisconnected(ComponentNamename){
  20. mIaidlServerService=null;
  21. }
  22. publicvoidonServiceConnected(ComponentNamename,IBinderservice){
  23. mIaidlServerService=IAIDLServerService.Stub.asInterface(service);
  24. //aidl通信
  25. try{
  26. StringmText="Sayhello:"+mIaidlServerService.sayHello()+"/n";
  27. mText+="书名:"+mIaidlServerService.getBook().getBookName()+"/n";
  28. mText+="价格:"+mIaidlServerService.getBook().getBookPrice();
  29. mTextView.setText(mText);
  30. }catch(RemoteExceptione){
  31. e.printStackTrace();
  32. }
  33. }
  34. };
  35. @Override
  36. publicvoidonCreate(BundlesavedInstanceState){
  37. super.onCreate(savedInstanceState);
  38. setContentView(R.layout.main);
  39. //初始化控件
  40. mTextView=(TextView)findViewById(R.id.textview);
  41. mButton=(Button)findViewById(R.id.button);
  42. //增加事件响应
  43. mButton.setOnClickListener(newOnClickListener(){
  44. publicvoidonClick(Viewv){
  45. //bindService
  46. Intentservice=newIntent("com.chapter8.aidl.IAIDLServerService");
  47. bindService(service,mConnection,BIND_AUTO_CREATE);
  48. }
  49. });
  50. }
  51. }

第五步:运行客户端工程,效果如下:

Android 中的AIDL_第4张图片Android 中的AIDL_第5张图片

Ok,上面就完整的作了一个Aidl开发的流程,有什么不对的地方希望大家多多指教,今天就讲到这里。谢谢!

更多相关文章

  1. 我的Android NDK之旅(五),在Mac上用eclipse手动编写代码向android开
  2. android开源代码
  3. Android 混淆代码学习以及Android加密工具--APKProtect的使用
  4. android代码实现免提功能
  5. Android解析XML到对象工具类
  6. CentOS 下载 Android 源代码。

随机推荐

  1. 编程回忆之Android回忆(Android应用参数的
  2. Android中Data和String数据类型转换
  3. Android利用Looper在子线程中改变UI
  4. 录音及播放音频文件
  5. Android全屏对话框(附带延时关闭效果)
  6. Android(安卓)PendingIntent和Intent
  7. android获取系统当前年月日时分秒的时间
  8. 使用NanoHTTPD在android实现web迷你服务
  9. Android下的SQLite数据库的相关操作及And
  10. Android(安卓)NDK编译时出现的问题以及解