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文件,如上图红色部分:
[java] view plain copy- packagecom.chapter8.aidl;
- importcom.chapter8.aidl.Book;
- interfaceIAIDLServerService{
- StringsayHello();
- BookgetBook();
- }
第二步:因为这个接口里有传递对象,所以对象要特殊处理一下,这里继承了Parcelable,Book.java代码如下:
如果大家不明的地方,请参见,下面连接的文章:
Android高手进阶教程(十七)之---Android中Intent传递对象的两种方法(Serializable,Parcelable)!
[java] view plain copy- packagecom.chapter8.aidl;
- importandroid.os.Parcel;
- importandroid.os.Parcelable;
- publicclassBookimplementsParcelable{
- privateStringbookName;
- privateintbookPrice;
- publicBook(){
- }
- publicBook(Parcelparcel){
- bookName=parcel.readString();
- bookPrice=parcel.readInt();
- }
- publicStringgetBookName(){
- returnbookName;
- }
- publicvoidsetBookName(StringbookName){
- this.bookName=bookName;
- }
- publicintgetBookPrice(){
- returnbookPrice;
- }
- publicvoidsetBookPrice(intbookPrice){
- this.bookPrice=bookPrice;
- }
- publicintdescribeContents(){
- return0;
- }
- publicvoidwriteToParcel(Parcelparcel,intflags){
- parcel.writeString(bookName);
- parcel.writeInt(bookPrice);
- }
- publicstaticfinalParcelable.Creator<Book>CREATOR=newCreator<Book>(){
- publicBookcreateFromParcel(Parcelsource){
- returnnewBook(source);
- }
- publicBook[]newArray(intsize){
- returnnewBook[size];
- }
- };
- }
第三步:写一个与Book类对应的aidl,命名为Book.aidl,代码非常简单,代码如下:
[java] view plain copy- parcelableBook;
第四步:新建一个名为AidlServerService的Service.代码如下:
[java] view plain copy- packagecom.chapter8.aidl;
- importcom.chapter8.aidl.IAIDLServerService.Stub;
- importcom.chapter8.aidl.IAIDLServerService;
- importandroid.app.Service;
- importandroid.content.Intent;
- importandroid.os.IBinder;
- importandroid.os.RemoteException;
- publicclassAidlServerServiceextendsService{
- @Override
- publicIBinderonBind(Intentintent){
- returnmBinder;
- }
- /**
- *在AIDL文件中定义的接口实现。
- */
- privateIAIDLServerService.StubmBinder=newStub(){
- publicStringsayHello()throwsRemoteException{
- return"Hello";
- }
- publicBookgetBook()throwsRemoteException{
- BookmBook=newBook();
- mBook.setBookName("Android应用开发");
- mBook.setBookPrice(50);
- returnmBook;
- }
- };
- }
第五步:在AndroidManifest.xml注册Service,代码如下:
[java] view plain copy- <?xmlversion="1.0"encoding="utf-8"?>
- <manifestxmlns:android="http://schemas.android.com/apk/res/android"
- package="com.chapter8.aidl"
- android:versionCode="1"
- android:versionName="1.0">
- <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
- <activityandroid:name="AidlServerActivity"
- android:label="@string/app_name">
- <intent-filter>
- <actionandroid:name="android.intent.action.MAIN"/>
- <categoryandroid:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- <serviceandroid:name="AidlServerService"
- android:process=":remote">
- <intent-filter>
- <actionandroid:name="com.chapter8.aidl.IAIDLServerService"></action>
- </intent-filter>
- </service>
- </application>
- </manifest>
第六步:运行服务端工程,到设备上,好让客户端调用,服务端的Activity什么都没做.效果如下:
客户端的具体实现步骤:
第一步:新建客户端工程,目录结构如下:
第二步:引入Aidl文件以及用到的类,如上面的com.chapter8.aidl包。直接从服务端里代码copy过来就OK.
第三步:修改main.xml布局文件,增加一个按钮,代码如下:
[java] view plain copy- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:id="@+id/textview"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <Button
- android:id="@+id/button"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="调用AIDL服务"
- />
- </LinearLayout>
第四步:修改AidlClientActivity.java代码如下:
[java] view plain copy- packagecom.chapter8.aidlclient;
- importcom.chapter8.aidl.IAIDLServerService;
- importandroid.app.Activity;
- importandroid.content.ComponentName;
- importandroid.content.Intent;
- importandroid.content.ServiceConnection;
- importandroid.os.Bundle;
- importandroid.os.IBinder;
- importandroid.os.RemoteException;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- importandroid.widget.TextView;
- publicclassAidlClientActivityextendsActivity{
- privateTextViewmTextView;
- privateButtonmButton;
- privateIAIDLServerServicemIaidlServerService=null;
- privateServiceConnectionmConnection=newServiceConnection(){
- publicvoidonServiceDisconnected(ComponentNamename){
- mIaidlServerService=null;
- }
- publicvoidonServiceConnected(ComponentNamename,IBinderservice){
- mIaidlServerService=IAIDLServerService.Stub.asInterface(service);
- //aidl通信
- try{
- StringmText="Sayhello:"+mIaidlServerService.sayHello()+"/n";
- mText+="书名:"+mIaidlServerService.getBook().getBookName()+"/n";
- mText+="价格:"+mIaidlServerService.getBook().getBookPrice();
- mTextView.setText(mText);
- }catch(RemoteExceptione){
- e.printStackTrace();
- }
- }
- };
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //初始化控件
- mTextView=(TextView)findViewById(R.id.textview);
- mButton=(Button)findViewById(R.id.button);
- //增加事件响应
- mButton.setOnClickListener(newOnClickListener(){
- publicvoidonClick(Viewv){
- //bindService
- Intentservice=newIntent("com.chapter8.aidl.IAIDLServerService");
- bindService(service,mConnection,BIND_AUTO_CREATE);
- }
- });
- }
- }
第五步:运行客户端工程,效果如下:
Ok,上面就完整的作了一个Aidl开发的流程,有什么不对的地方希望大家多多指教,今天就讲到这里。谢谢!
更多相关文章
- 我的Android NDK之旅(五),在Mac上用eclipse手动编写代码向android开
- android开源代码
- Android 混淆代码学习以及Android加密工具--APKProtect的使用
- android代码实现免提功能
- Android解析XML到对象工具类
- CentOS 下载 Android 源代码。