一、AIDL介绍
aidl是 Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。
Aidl与其他通讯的区别: “只有当你允许来自不同的客户端访问你的服务并且需要处理多线程问题时你才必须使用AIDL”,其他情况下你都可以选择其他方法,如使用Messager,也能跨进程通讯。可见AIDL是处理多线程、多客户端并发访问的。而Messager是单线程处理。
二、AIDL使用
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class AIDLRemoteService extends Service {
private static final String TAG = "AIDLRemoteService";
private final myAIDL.Stub mBinder=new myAIDL.Stub(){
@Override
public void testMethod() throws RemoteException {
Log.d(TAG, "testMethod: "+"this is myAIDLTest");
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
// myAIDL.aidl
package com.example.aidltest;
// Declare any non-default types here with import statements
interface myAIDL{
void testMethod();
}
package com.example.aidltest;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private Button btnBindService;
private Button btnStartMethod;
private myAIDL mMyAIDL;
private ServiceConnection mServiceConnection = new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.e(TAG, "onServiceConnected");
mMyAIDL = myAIDL.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name)
{
Log.e(TAG, "onServiceDisconnected");
mMyAIDL = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
btnBindService =(Button) findViewById(R.id.btn_bind_service);
btnStartMethod=(Button)findViewById(R.id.btn_start_method);
btnBindService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,AIDLRemoteService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
});
btnStartMethod.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mMyAIDL!=null){
try {
mMyAIDL.testMethod();
} catch (RemoteException e) {
e.printStackTrace();
}
}else{
Toast.makeText(MainActivity.this, "服务被异常杀死,请重新开启。", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
}
}
里面有四个个重要的文件,一个是myAIDL.aidl文件,一个是AIDLRemoteService.java文件,一个是MainActivity文件,最后一个是myAIDL.Java文件。前面三个文件不做多的分析,主要分析myAIDL.java文件。
三、AIDL.java文件
从其中我们可以看出AIDL.java文件实际上是对Binder进行了代理模式处理的,重写了Binder里面的onTransact()方法,Proxy负责给远端Service发送信息,Stub负责重写接口方法、接收客户端的信息、进行调用方法
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: E:\\workplace2\\AIDLTest\\src\\com\\example\\aidltest\\myAIDL.aidl
*/
package com.example.aidltest;
// Declare any non-default types here with import statements
public interface myAIDL extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
com.example.aidltest.myAIDL {
private static final java.lang.String DESCRIPTOR = "com.example.aidltest.myAIDL";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.aidltest.myAIDL interface,
* generating a proxy if needed.
*/
public static com.example.aidltest.myAIDL asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.example.aidltest.myAIDL))) {
return ((com.example.aidltest.myAIDL) iin);
}
return new com.example.aidltest.myAIDL.Stub.Proxy(obj);
}
@Override
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_testMethod: {
data.enforceInterface(DESCRIPTOR);
this.testMethod();
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.aidltest.myAIDL {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public void testMethod() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_testMethod, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_testMethod = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public void testMethod() throws android.os.RemoteException;
}