AIDL实现跨进程通信

AIDL的全称是什么?如何工作?能处理哪些类型的数据?

AIDL的英文全称是Android Interface Define Language

当B进程要去调用A进程中的service时,并实现通信,我们通常都是通过AIDL来操作的

A工程:
首先我们在项目所在的目录下建一个包 (包名自己指定),在包中创建一个IServer.aidl文件 如下图中标注1所示
ADT插件会在gen目录下自动生成一个IServer.java文件,该类中含有一个名为IServer.stub的内部类,该内部类中含有aidl文件接口的get方法。
如下图中标注3所示:
AIDL实现跨进程通信_第1张图片

在IService.aidl文件中我们自定义一个接口,含有方法get。代码如下:

package com.example.aidl;
interface IServer{
String getInfo(String info);
}

说明一:aidl文件的位置不固定,可以任意
然后定义自己的MyServer类(如上图中标注2所示),在MyServer类中自定义一个内部类去继承IServer.stub这个内部类,实现get方法。在onBind方法中返回这个内部类的对象,系统会自动将这个对象封装成IBinder对象,传递给他的调用者。MyServer代码如下:

public class MyServer extends Service {

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return mBinder;
}

public Binder mBinder = new IServer.Stub() {

    @Override
    public String getInfo(String info) throws RemoteException {
        // TODO Auto-generated method stub
        if ("你好".equals(info)) {
            return "你好,我是你大爷";
        } else {
            return "你好,你是我侄子";
        }
    }
};

}
其次需要在AndroidManifest.xml文件中配置MyServer类,代码如下:
AIDL实现跨进程通信_第2张图片

为什么要指定调用AIDL服务的ID,就是要告诉外界MyServer这个类能够被别的进程访问,只要别的进程知道这个ID,正是有了这个ID,B工程才能找到A工程实现通信。
说明:AIDL并不需要权限
B工程:
首先我们要将A工程中生成的IServer.java文件拷贝到B工程中如下图:
AIDL实现跨进程通信_第3张图片

在bindService方法中绑定aidl服务
  绑定AIDL服务就是将IServer的ID作为intent的action参数。代码如下:
 public class MainActivity extends Activity {

private static final String TAG = "MainActivity";
private MyConn conn;
private IServer mServer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    Intent service = new Intent("com.example.aidl");
    conn = new MyConn();
    bindService(service, conn, BIND_AUTO_CREATE);
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if (conn != null) {
        unbindService(conn);
    }
}

class MyConn implements ServiceConnection {

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

    @Override
    public void onServiceDisconnected(ComponentName name) {
        // TODO Auto-generated method stub

    }

}

// 点击事件
public void bind(View v) throws RemoteException {
// 向服务器端发送信息
String info = mServer.getInfo(“你好”);

    Toast.makeText(this, "从服务器端返回的信息为" + info, 1).show();
}

}

  说明:如果我们单独将IServer.aidl文件放在一个包里,那个在我们将gen目录下的该包拷贝到B工程中。如果我们将IServer.aidl文件和我们的其他类存放在一起,那么我们在B工程中就要建立相应的包,以保证IServer.java文件的报名正确,我们不能修改IServer.java文件

  ServiceConnection的onServiceConnected(ComponentName name, IBinder service)方法中的service参数就是A工程中MyService类中继承了IServer.stub类的内部类的对象。

你可能感兴趣的:(服务,进程间通信)