1.簡單使用
利用android studio開發(fā)aidl還是非常方便的吧享,建立一個aidl的后綴文件突委,在service與activity分別完成實現(xiàn)與引用就可以了
舉例:
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);
}
}
輸出結(jié)果
I/RemoteService: information
2.理解proxy與stub的工作流程
aidl的后綴文件是Android studio的簡化處理鬼佣,看一下IMyAidlInterface具體實現(xiàn)
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包含了一個靜態(tài)內(nèi)部類Stub,并且Stub也繼承了IMyAidlInterface休弃,所以Stub是IMyAidlInterface的具體實現(xiàn)介牙,而Stub又是一個抽象類,最終的實現(xiàn)在RemoteService中
Stub內(nèi)部包含了一個靜態(tài)內(nèi)部類Proxy奋岁,同樣實現(xiàn)了接口IMyAidlInterface
可以通過前面的例子梳理一下Stub-proxy的工作流程
- RemoteService中的IBinder對象mServiceBinder是Stub的具體實現(xiàn)思瘟,在RemoteService和activity綁定的時候被返回
- 被返回的mServiceBinder最終是作為onServiceConnected中的參數(shù),
- Activity端會調(diào)用Stub中的靜態(tài)方法asInterface闻伶,mServiceBinder作為參數(shù)滨攻,最后拿到IMyAidlInterface接口對象myAidlInterface
在asInterface方法中首先會判斷Binder是否處在當(dāng)前進程,否則構(gòu)造Proxy并返回,構(gòu)造Proxy時光绕,把mServiceBinder賦值給mRemote女嘲,Proxy中實現(xiàn)的接口getInformation會調(diào)用mRemote的transact方法,而Binder的通信是靠transact和onTransact實現(xiàn)的诞帐,最后會走到Stub的onTransact欣尼,完成對mServiceBinder的調(diào)用
所以,aidl通信體現(xiàn)著代理模式的設(shè)計思想景埃,RemoteService具體實現(xiàn)了Stub媒至,Proxy是Stub在本地Activity的代理對象,Proxy與Stub依靠transact和onTransact通信谷徙,Proxy與Stub的封裝設(shè)計最終很方便地完成了Activity與RemoteService跨進程通信