AIDL进程间通信

Android中使用AIDL技术约束进程通信规则(类似于接口的定义语言)

示例:通过AIDL访问远程服务(remote service)实现通过学生学号查找姓名


远程服务(remote service)配置

1.创建不带Activity的AndroidApplication


2.src目录下创建package并在里面添加文件StudentQuery.aidl

按照接口的方式编写,并去掉访问描述符(public,private等)

package com.example.aidl;//AIDL 描述规则interface StudentQuery {String queryStudent (int number);}

这个时候在gen文件夹下会生成一大堆代码,主要是StudentQuery接口


3.创建学生查询服务(com.example.remote.service.StudentQueryService.java)继承于Service,

并在AndroidManifest.xml文件中添加服务的隐式意图:

                                        

重写onBinder方法,在onBinder方法中,我们要返回IBinder接口对象,这样访问者才可以使用Service类提供的服务,因此,我们声明并创建binder对象:

private IBinder binder  = new  StudentQueryBinder();


4.此时StudentQueryBinder类不存在,

我们创建它(com.example.remote.service.StudentQueryBinder.java)并且要具备跨应用通信的功能,这个时候就需要继承刚刚自动生成的com.example.aidl.StudentQuery.Stub类,并实现IBinder接口,点击生成未实现的方法(queryStudent),事实上通过查看Stub的源码会发现:

public static abstract class Stub extends android.os.Binder implements com.example.aidl.StudentQuery

Stub在继承Binder同时实现StudentQuery接口

代码:

public class StudentQueryBinder extends Stub  implements IBinder{@Overridepublic String queryStudent(int number) throws RemoteException {return null;}}

在queryStudent方法中实现自己的查询服务(本例中简单起见不访问数据库)

至此完成远程服务代码编写。


访问者(客户端代码编写)

这里的需求是当click button的时候完成查询,并将结果显示出来。


1.首先不能忘记的是在src下创建并编写同样的aidl文件,这样在客户端的gen目录下也会生成同样的java文件。


2.为MainActivity绑定服务。

使用bindService方法,我们看到它需要三个参数:

第一个是Intent对象,我们创建并设定隐式意图:

Intent service = new Intent("com.example.student.query");

第三个是一个标志表明绑定中的操作,这里我们使用:

public static final int BIND_AUTO_CREATE = 0x0001;

第二个参数就要好好讲讲,它是实现ServiceConnection的类的对象

所以,我们首先创建内部类StudentConnection并实现ServiceConnection接口

编写未实现的方法:

@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {studentQuery=StudentQuery.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {studentQuery=null;}

这个时候我们获取服务返回的IBinder的对象,此处由于是远程通信,需要使用语句StudentQuery.Stub.asInterface(service);来进行转换(本地服务就不需要)

那么现在我们就可以通过queryStudent接口对象来使用服务了。


3.我们希望通过button来访问服务,这样为button添加一个onClick属性并指定方法:queryStudent

在MainActivity中编写这个方法

public void queryStudent(View v){                   intstudentID=Integer.valueOf(editTextStudentID.getText().toString());                   try{                            textViewResult.setText(studentQuery.queryStudent(studentID));                   }catch (RemoteException e) {                            e.printStackTrace();                   }         }

我们看到通过studentQuery对象来调用queryStudent方法来实现服务的访问。



附录:

com.example.remoteserviceclient.MainActivity.java

public class MainActivity extends Activity {private EditText editTextStudentID;private TextView textViewResult;private StudentQuery studentQuery;private StudentConnection conn = new StudentConnection();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editTextStudentID = (EditText)this.findViewById(R.id.studentID);textViewResult=(TextView)this.findViewById(R.id.textViewResult);Intent service = new Intent("com.example.student.query");bindService(service, conn, BIND_AUTO_CREATE);}public void queryStudent(View v){int studentID=Integer.valueOf(editTextStudentID.getText().toString());try {textViewResult.setText(studentQuery.queryStudent(studentID));} catch (RemoteException e) {e.printStackTrace();}}@Overrideprotected void onDestroy() {unbindService(conn);super.onDestroy();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}private final class StudentConnection implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {studentQuery=StudentQuery.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {studentQuery=null;}}}


com.example,remote.service.StudentQueryBinder.java

public class StudentQueryBinder extends Stub  implements IBinder{private String[] names = { "张笑", "杨景", "衡通", "阎树信" ,"何宇同"};private String query(int id) {if (id < 254 && id > 248)return names[253 - id];return "查询结果不在范围";}@Overridepublic String queryStudent(int number) throws RemoteException {return query(number);}}

com.example,remote.service.StudentQueryService.java

public class StudentQueryService extends Service {private IBinder binder=new StudentQueryBinder();@Overridepublic IBinder onBind(Intent intent) {return binder;}}




更多相关文章

  1. tcping测试服务器TCP端口
  2. Android(安卓)模拟器访问局域网服务器
  3. Android(安卓)微信接入公共平台回调失败
  4. Android(安卓)TabViewActivity中overridePendingTransition失效
  5. Android数据库(SQLiteDatabase)使用小结
  6. Unable to start activity ComponentInfo{com.first/com.first.G
  7. Android(安卓)中不同的系统版本隐藏和显示systemui方法
  8. 利用AccessibilityService实现“微信红包”插件
  9. android 获取当前时间精确到毫秒的两种方法

随机推荐

  1. Android使用JavaMail后台发送邮件遇到的
  2. Android网络编程
  3. android 源代码构建和运行cts
  4. Android(安卓)创建快捷方式
  5. Android中,活动的几种启动模式
  6. zoomable android textview
  7. android 屏保锁中屏掉按键和HOME键的方法
  8. Android 保存图片到图库
  9. Android TableLayout的使用
  10. Android UI 开发入门—线性布局