700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android--使用AIDL和远程服务实现线程通信

Android--使用AIDL和远程服务实现线程通信

时间:2022-08-15 23:52:05

相关推荐

Android--使用AIDL和远程服务实现线程通信

笔记摘要:

在Android中,每个应用都有自己的进程,当需要在不同的进程之间传递对象时,由于java不支持跨进程内存共享,因此要传递对象,需要把对象解析成操作系统能

够理解的数据格式,以达到跨界对象访问的目的。在javaEE中,采用RMI通过序列化传递对象,在Android中,则采用AIDL(AndroidInterfaceDefinitionLanguage:

接口定义语言)方式实现。

一、AIDL介绍

AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC),AIDL的IPC机制和EJB所采用

的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。由于进程之间的通

信信息需要双向转换,所以Android采用代理类在背后实现了信息的双向转换,代理类由Android编译器生成,对开发人员来说是透明的。

所以我们在定义服务端的时候需要定义一个AIDL类型的文件指定一种协议来确保服务端和客户端的通信。

二、创建AIDL协议的方式及注意事项:

在B应用中创建“aidl文件,aidl文件的定义和接口的定义很类似,所以我们可以新建一个接口StudentQuery,在接口中定义一些方法后,修改该文件类型为aidl,

即可完成该aidl文件的创建。

编写AIDL文件时,需要注意的事项:

1、接口名和aidl文件名相同。

2、接口和方法前不用加访问权限修饰符public,private,protected,也不能加final,static

3、Aidl默认支持的类型包括java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),使用这些类型不需要import声明。对于List和Map中的元素类型必须是aidl支持的类型。如果使用自定义类型作为参数或返回值,自定义类型必须实现Parcelable接口、

4、自定义类型和aidl生成的其它接口类型在aidl描述文件中,应该显示import,即便在该类和定义的包在同一个包中。

5、在aidl文件中所有的非java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入参数。

6、Java原始类型默认的标记为in,不能为其它标记。

程序中需要注意:

当完成aidl文件创建后,eclipse会自动在项目中的gen目录中同步生成StudentQuery.java接口文件。接口文件生成一个Stub的抽象类,里面包括aidl定义的方法,

还包括一些其他辅助方法。值得注意的是asInterface(IbinderiBinder)返回接口类型的实例,对于远程服务调用,远程服务返回给客户端的对象为代理对象,

客户端在onServiceConnected(ComponentNamename,IBinderservice)方法引用该对象时,不能直接强转成接口类型的实例,而应该使用asInterface(IBinderiBinder)

进行类型转换。

三、效果图

四、代码体现

说明:

这里通过在一个Android客户端进程中向Android服务端发送业务请求,服务端进行处理后,返回给客户端结果。和本地服务一样,它们之间同样

通过Binder来进行通信

4.1 服务端

AIDL文件

package cn.xushuai.aidl;//AIDL描述,用于编译器生成通讯协议interface StudentQuery {String queryStudent(int number);}

注册业务类,同时定义一个激活名,用于客户端调用该业务类

<service android:name=".StudentQueryService"><!-- 采用隐式激活服务,激活名称为cn.xushuai.student.query --><intent-filter ><action android:name="cn.xushuai.student.query"/></intent-filter></service>

业务类

说明:

这里的Binder继承的是gen根目录下,AIDL文件生成的相应的文件中的StudentQuery接口的内部类Stub,它已经继承了Binder对象,

这样做的目的就是为了让该服务具有远程通讯能力。

但是这里的binder对象是一个代理。

package cn.xushuai.remote.service;import cn.xushuai.aidl.StudentQuery.Stub;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class StudentQueryService extends Service {private String[] names = {"张三","李四","王五"};private IBinder binder = new StudentQueryBinder();@Overridepublic IBinder onBind(Intent intent) {return binder;//返回给客户端一个具有远程通讯能力的binder对象,其实是一个代理}private String query(int number){if(number > 0 && number < 4){return names[number-1];}return null;}//为了让该服务具有远程通讯的能力,所以继承编译器生成的通讯类中的Stub,它继承自Binderprivate final class StudentQueryBinder extends Stub{public String queryStudent(int number) throws RemoteException {return query(number);}}}

4.2 客户端

同样在客户端也需要相同的AIDL文件

package cn.xushuai.aidl;//AIDL描述,用于编译器生成通讯协议interface StudentQuery {String queryStudent(int number);}

客户端页面代码

<EditText android:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/studentno"/><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/studentno"android:id="@+id/button"android:text="@string/button"/><TextView android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_below="@id/button"android:id="@+id/resultView"/>

客户端的业务类

package cn.xushuai.remoteservice.client;import cn.xushuai.aidl.StudentQuery;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.app.Activity;import ponentName;import android.content.Intent;import android.content.ServiceConnection;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class RemoteServiceClient extends Activity {private EditText studentno;private TextView resultView;private StudentServiceConnection conn = new StudentServiceConnection();private StudentQuery studentQuery;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_remote_service_client);studentno = (EditText)this.findViewById(R.id.studentno);Button button = (Button) this.findViewById(R.id.button);resultView = (TextView) this.findViewById(R.id.resultView);button.setOnClickListener(new ButtonClickListener());Intent service = new Intent("cn.xushuai.student.query");bindService(service, conn, BIND_AUTO_CREATE);//绑定后自动创建服务}//实现一个服务连接对象private class StudentServiceConnection implements ServiceConnection{public void onServiceConnected(ComponentName name, IBinder service) {//将返回的binder代理转换为接口对象studentQuery = StudentQuery.Stub.asInterface(service);}public void onServiceDisconnected(ComponentName name) {studentQuery = null;}}//当Activity摧毁的时候,解除与服务的绑定@Overrideprotected void onDestroy() {unbindService(conn);super.onDestroy();}private final class ButtonClickListener implements View.OnClickListener{public void onClick(View v) {String number = studentno.getText().toString();int num = Integer.valueOf(number);try {String name = studentQuery.queryStudent(num);resultView.setText(name);} catch (RemoteException e) {e.printStackTrace();}}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。