1.簡單使用
利用android studio開發aidl還是非常方便的,建立一個aidl的后綴文件,在service與activity分別完成實現與引用就可以了
舉例:
aidl文件
interface IMyAidlInterface {
void getInformation();
}
service
public class RemoteService extends Service {
private IBinder mServiceBinder = new IMyAidlInterface.Stub(){
@Override
public void getInformation() {
Log.i("RemoteService","information");
}
};
public RemoteService() {
}
@Override
public IBinder onBind(Intent intent) {
return mServiceBinder;
}
}
activity
public class MainActivity extends AppCompatActivity {
IMyAidlInterface myAidlInterface;
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
myAidlInterface.getInformation();
} catch (RemoteException ex) {
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startAndBindService();
}
private void startAndBindService() {
Intent serviceIntent = new Intent(MainActivity.this, RemoteService.class);
bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE);
}
}
輸出結果
I/RemoteService: information
2.理解proxy與stub的工作流程
aidl的后綴文件是Android studio的簡化處理,看一下IMyAidlInterface具體實現
public interface IMyAidlInterface extends android.os.IInterface
{
public static abstract class Stub extends android.os.Binder implements com.example.testapplication.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.example.testapplication.IMyAidlInterface";
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
public static com.example.testapplication.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.testapplication.IMyAidlInterface))) {
return ((com.example.testapplication.IMyAidlInterface)iin);
}
return new com.example.testapplication.IMyAidlInterface.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_getInformation:
{
data.enforceInterface(DESCRIPTOR);
this.getInformation();
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.testapplication.IMyAidlInterface
{
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 getInformation() 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_getInformation, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_getInformation = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public void getInformation() throws android.os.RemoteException;
}
我們聲明的接口IMyAidlInterface包含了一個靜態內部類Stub,并且Stub也繼承了IMyAidlInterface,所以Stub是IMyAidlInterface的具體實現,而Stub又是一個抽象類,最終的實現在RemoteService中
Stub內部包含了一個靜態內部類Proxy,同樣實現了接口IMyAidlInterface
可以通過前面的例子梳理一下Stub-proxy的工作流程
- RemoteService中的IBinder對象mServiceBinder是Stub的具體實現,在RemoteService和activity綁定的時候被返回
- 被返回的mServiceBinder最終是作為onServiceConnected中的參數,
- Activity端會調用Stub中的靜態方法asInterface,mServiceBinder作為參數,最后拿到IMyAidlInterface接口對象myAidlInterface
在asInterface方法中首先會判斷Binder是否處在當前進程,否則構造Proxy并返回,構造Proxy時,把mServiceBinder賦值給mRemote,Proxy中實現的接口getInformation會調用mRemote的transact方法,而Binder的通信是靠transact和onTransact實現的,最后會走到Stub的onTransact,完成對mServiceBinder的調用
所以,aidl通信體現著代理模式的設計思想,RemoteService具體實現了Stub,Proxy是Stub在本地Activity的代理對象,Proxy與Stub依靠transact和onTransact通信,Proxy與Stub的封裝設計最終很方便地完成了Activity與RemoteService跨進程通信