AIDL进程间通信
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;}}
更多相关文章
- tcping测试服务器TCP端口
- Android(安卓)模拟器访问局域网服务器
- Android(安卓)微信接入公共平台回调失败
- Android(安卓)TabViewActivity中overridePendingTransition失效
- Android数据库(SQLiteDatabase)使用小结
- Unable to start activity ComponentInfo{com.first/com.first.G
- Android(安卓)中不同的系统版本隐藏和显示systemui方法
- 利用AccessibilityService实现“微信红包”插件
- android 获取当前时间精确到毫秒的两种方法