Android AIDL 詳解

爲了使其他的應用程序也可以訪問本應用程序提供的服務,Android系統採用了遠程過程調用(Remote Procedure Call,RPC)方式來實現。與很多其他的基於RPC的解決方案一樣,Android使用一種接口定義語言(Interface Definition Language,IDL)來公開服務的接口。我們知道4個Android應用程序組件中的3個(Activity、BroadcastReceiver和ContentProvider)都可以進行跨進程訪問,另外一個Android應用程序組件Service同樣可以。因此,可以將這種可以跨進程訪問的服務稱爲AIDL(Android Interface Definition Language)服務。

說了一堆沒用的那麼AIDL 到底如何應用在我們的開發中,就是當我們的程序需要訪問其他程序的服務中的數據。或者我們的程序開了多進程的需要數據交互的時候就可以使用。其實aidl 用的就是binder機制。

那麼如何使用aidl 呢 我這裏 講實現代碼 按照順序 貼出來。

1.創建 aidl 文件 定義一個接口 負責定義 服務端提供的方法。

<span style="font-size:18px;">package com.yu.alitestpay;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(String str);
}</span>

3.創建 Service 類 。 實現service 端的具體方法。供 客戶端使用 。

<span style="font-size:18px;">package com.yu.alitestpay;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;</span>
<span style="font-size:18px;">public class Mservice extends Service
{
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
}
    private IMyAidlInterface.Stub binder= new  IMyAidlInterface.Stub(){
        @Override
        public void basicTypes(String str) throws RemoteException {
                     Log.i("2024","服務端執行了方法");
        }
    };
}
</span>
4.客戶端 通過 onServiceConnected 方法 調用服務端 方法 完成數據交互 。
<span style="font-size:18px;"></pre><pre name="code" class="html">ServiceConnection cs=new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                IMyAidlInterface proxy=IMyAidlInterface.Stub.asInterface(service);
                try {
                    proxy.basicTypes("2342");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };</span>

下面貼出 IMyAidlInterface 類的源碼   講下 binder 在aidl 中的 應用。

查看 IMyAidlInterface.java 中可以看到兩個類 一個stub  一個 proxy   Stub 集成了binder 實現了IMyAidlInterface 那麼IMyAidlInterface 中的抽象方法
他沒有實現 爲什麼 是留着我們寫 service 的時候交給service寫 具體 實現方法。就像這裏的 new  IMyAidlInterface.Stub() 這裏就具體實現了方法
 服務端 
我們在 onbind 的時候返回了binder 對象 也就是實現了具體抽象方法的Stub 對象 。
客戶端
客戶端在  這裏用stub 獲得了一個對象 其實獲得就是proxy 我們客戶端的basicTypes()方法  調用了 stub 的transact sub繼承了 binder 所以看源碼發現 transact 的時候會調用ontransact  那麼 stub 的ontransact 方法調用了什麼  調用了 this.basicTypes  那麼這個方法就是 這裏面實現的方法
整個交互過程完成 一個典型的binder 機制。

<span style="font-size:18px;">/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: F:\\android\\AliTestPay\\app\\src\\main\\aidl\\com\\yu\\alitestpay\\IMyAidlInterface.aidl
 */
package com.yu.alitestpay;
// Declare any non-default types here with import statements

public interface IMyAidlInterface extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.yu.alitestpay.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.yu.alitestpay.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.yu.alitestpay.IMyAidlInterface interface,
 * generating a proxy if needed.
 */
public static com.yu.alitestpay.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.yu.alitestpay.IMyAidlInterface))) {
return ((com.yu.alitestpay.IMyAidlInterface)iin);
}
return new com.yu.alitestpay.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_basicTypes:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
this.basicTypes(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.yu.alitestpay.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;
}
/**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
@Override public void basicTypes(java.lang.String str) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(str);
mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
/**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
public void basicTypes(java.lang.String str) throws android.os.RemoteException;
}
</span>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章