aidl是 Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。还有一个就是IPC(inter process communication),表示的进程间通信。
这编博客就是一个入门的例子,告诉我们大家如何使用AIDL通信。好了废话不多说,现在就开始进入我们的例子:
首先我们需要新建两个工程,然后再两个工程内都存放一个相同的AIDL文件,如下图:
那么下面我们来说说AIDL文件是如何编写的,其实也很简单,大家可以把它看成一个interface,只不过这个InterFace比较特殊,它里面不能用修饰符(比如说public,protected,private)。
AidlService.aidl文件如下:
package cn.com.aidl.service;
interface AidlService{
int add(in int a,in int b);
}
当那保存好后,就会在gen目录下自动创建一个java文件,那么在该java文件的内部会有一个stub内部类,这个类是比较重要的。
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\workspace\\Androidworkspace\\ZAIDLService\\src\\cn\\com\\aidl\\service\\AidlService.aidl
*/
package cn.com.aidl.service;
public interface AidlService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements cn.com.aidl.service.AidlService
{
private static final java.lang.String DESCRIPTOR = "cn.com.aidl.service.AidlService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an cn.com.aidl.service.AidlService interface,
* generating a proxy if needed.
*/
public static cn.com.aidl.service.AidlService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof cn.com.aidl.service.AidlService))) {
return ((cn.com.aidl.service.AidlService)iin);
}
return new cn.com.aidl.service.AidlService.Stub.Proxy(obj);
}
public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements cn.com.aidl.service.AidlService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public int add(int a, int b) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(a);
_data.writeInt(b);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int add(int a, int b) throws android.os.RemoteException;
}
其实这个类对于刚刚接触的人来说,可能有点复杂,里面做了以下几件事,1、判断当前的应用和通信的应用是否是在同一个进程中;2、会创建一个代理对象 ; 3、主要是通过onTransact()方法来调用远程的方法
那么这些具体的是如何进行的,大家可以去网上百度Aidl源码分析,就可以找到哦!
之后我们就需要新建一个Service,在这个Service内部返回一个AidlService的对象。我们也需要继承这个stub类。
AddService.java代码如下:
package cn.com.aidl.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class AddService extends Service {
private ServiceBindler mBinder = new ServiceBindler();
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
}
private class ServiceBindler extends AidlService.Stub {
public int add(int a, int b) throws RemoteException {
return a + b;
}
}
}
之后就需要在清单文件中配置该service,因为这是四大组件之一,那么这个意图在后面需要用到,这里先定义好。
下面就开始写另一个和它进行通信的运用:
main.xml文件如下:
下面是MainActivity,在这个Activity中,第一是要获得ServiceConnection对象,然后覆盖onServiceConnected()方法,在这个方法中获得AidlService的对象,用于后面调用。
package cn.com.aidl;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import cn.com.aidl.service.AidlService;
public class MainActivity extends Activity {
private EditText first, second;
private TextView textView;
private Button button;
private AidlService mService;
//获取到service对象
private ServiceConnection conn = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
mService = AidlService.Stub.asInterface(service);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
first = (EditText) this.findViewById(R.id.first);
second = (EditText) this.findViewById(R.id.second);
textView = (TextView) this.findViewById(R.id.textview);
button = (Button) this.findViewById(R.id.button);
//开启服务
startService();
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String a = first.getText().toString();
String b = second.getText().toString();
try {
int i = mService.add(Integer.parseInt(a),
Integer.parseInt(b));
textView.setText(a + " + " + b + " = " + i);
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
private void startService() {
Intent intent = new Intent();
//这个Action就是在另一个应用的清单文件中配置的
intent.setAction("cn.com.feng.service");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
if(conn != null){
unbindService(conn);
conn = null;
}
}
}
然后将这两个运行到手机上,就可以看见效果了。
枫