Android高手进阶教程(二十五)之---Android 中的AIDL!!!

大家好,好久不见,今天要给大家分享的是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的服务端另一个是客户端。

服务端的实现步骤:

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

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

  1. package com.chapter8.aidl;
  2. import com.chapter8.aidl.Book;
  3. interface IAIDLServerService {
  4. String sayHello();
  5. Book getBook();
  6. }

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

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

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

  1. package com.chapter8.aidl;
  2. import android.os.Parcel;
  3. import android.os.Parcelable;
  4. public class Book implements Parcelable {
  5. private String bookName;
  6. private int bookPrice;
  7. public Book(){
  8. }
  9. public Book(Parcel parcel){
  10. bookName = parcel.readString();
  11. bookPrice = parcel.readInt();
  12. }
  13. public String getBookName() {
  14. return bookName;
  15. }
  16. public void setBookName(String bookName) {
  17. this.bookName = bookName;
  18. }
  19. public int getBookPrice() {
  20. return bookPrice;
  21. }
  22. public void setBookPrice(int bookPrice) {
  23. this.bookPrice = bookPrice;
  24. }
  25. public int describeContents() {
  26. return 0;
  27. }
  28. public void writeToParcel(Parcel parcel, int flags) {
  29. parcel.writeString(bookName);
  30. parcel.writeInt(bookPrice);
  31. }
  32. public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {
  33. public Book createFromParcel(Parcel source) {
  34. return new Book(source);
  35. }
  36. public Book[] newArray(int size) {
  37. return new Book[size];
  38. }
  39. };
  40. }

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

  1. parcelable Book;

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

  1. package com.chapter8.aidl;
  2. import com.chapter8.aidl.IAIDLServerService.Stub;
  3. import com.chapter8.aidl.IAIDLServerService;
  4. import android.app.Service;
  5. import android.content.Intent;
  6. import android.os.IBinder;
  7. import android.os.RemoteException;
  8. public class AidlServerService extends Service {
  9. @Override
  10. public IBinder onBind(Intent intent) {
  11. return mBinder;
  12. }
  13. /**
  14. * 在AIDL文件中定义的接口实现。
  15. */
  16. private IAIDLServerService.Stub mBinder = new Stub() {
  17. public String sayHello() throws RemoteException {
  18. return "Hello";
  19. }
  20. public Book getBook() throws RemoteException {
  21. Book mBook = new Book();
  22. mBook.setBookName("Android应用开发");
  23. mBook.setBookPrice(50);
  24. return mBook;
  25. }
  26. };
  27. }

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

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

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

客户端的具体实现步骤:


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

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

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns: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代码如下:

  1. package com.chapter8.aidlclient;
  2. import com.chapter8.aidl.IAIDLServerService;
  3. import android.app.Activity;
  4. import android.content.ComponentName;
  5. import android.content.Intent;
  6. import android.content.ServiceConnection;
  7. import android.os.Bundle;
  8. import android.os.IBinder;
  9. import android.os.RemoteException;
  10. import android.view.View;
  11. import android.view.View.OnClickListener;
  12. import android.widget.Button;
  13. import android.widget.TextView;
  14. public class AidlClientActivity extends Activity {
  15. private TextView mTextView;
  16. private Button mButton;
  17. private IAIDLServerService mIaidlServerService = null;
  18. private ServiceConnection mConnection = new ServiceConnection() {
  19. public void onServiceDisconnected(ComponentName name) {
  20. mIaidlServerService = null;
  21. }
  22. public void onServiceConnected(ComponentName name, IBinder service) {
  23. mIaidlServerService = IAIDLServerService.Stub.asInterface(service);
  24. //aidl通信
  25. try {
  26. String mText = "Say hello: " + mIaidlServerService.sayHello() + "/n";
  27. mText += "书名: " + mIaidlServerService.getBook().getBookName()+"/n";
  28. mText += "价格: " + mIaidlServerService.getBook().getBookPrice();
  29. mTextView.setText(mText);
  30. } catch (RemoteException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. };
  35. @Override
  36. public void onCreate(Bundle savedInstanceState) {
  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(new OnClickListener(){
  44. public void onClick(View v) {
  45. //bindService
  46. Intent service = new Intent("com.chapter8.aidl.IAIDLServerService");
  47. bindService(service, mConnection,BIND_AUTO_CREATE);
  48. }
  49. });
  50. }
  51. }

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值