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{
	@Override
	public 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接口

编写未实现的方法:

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
	studentQuery=StudentQuery.Stub.asInterface(service);
		}
@Override
public 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();
	@Override
	protected 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();
		}
	}
	

	@Override
	protected void onDestroy() {
		unbindService(conn);
		super.onDestroy();
	}

	@Override
	public 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{

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			studentQuery=StudentQuery.Stub.asInterface(service);
		}

		@Override
		public 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 "查询结果不在范围";
	}
	@Override
	public 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();
	@Override
	public IBinder onBind(Intent intent) {
		return binder;
	}

}




你可能感兴趣的:(android)