1. 程式人生 > >Android studio 使用aidl和service進行程序間通訊

Android studio 使用aidl和service進行程序間通訊

一.概述
Android的Binder機制可以進行程序間通訊,但是Servicemanager這個類不公開,也就是我在自己的應用程式中無法使用Servicemanager的addService將我們自己定義的service註冊到binder中去,也無法通過getService獲取到對應的Service,那麼在我們的應用程式要如何來進行程序間通訊呢?利用aidl檔案和Service就可以進行通訊了.
二.編寫AIDL檔案
這裡寫圖片描述
在android studio按如上方法就可以建立aidl檔案,在aidl檔案中定義相關的功能,比如我在這裡就定義了一個getString 方法:
這裡寫圖片描述


將編寫好的aidl檔案編譯就會生成同名的.java檔案.為什麼生成的aidl檔案可以進行程序間通訊呢,因為它會自動幫我們生成對應的Binder子類stub和對應的proxy類,至於這2個類是做什麼的,這就涉及到了binder的知識,binder知識不是一下可以說清楚的,只能靠自己去研究了.
三.編寫Service

public class WatchDogService extends Service {


    public IBinder onBind(Intent intent) {

        return new MyBind();
    }

    @Override
public void onDestroy() { super.onDestroy(); } @Override public void onCreate() { super.onCreate(); } //這個類就是繼承自aidl編譯後生成的對應的.java件中的Stub類,它是Binder的子類 class MyBind extends test.Stub{ @Override public void basicTypes(int anInt, long aLong, boolean
aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } /**重寫 getString 方法 @Override public String getString(String str) throws RemoteException { return "遠端服務返回的資料:"+str; } } }

四.將servie註冊到AndroidManifest.xml中

 <service android:name="com.betterda.test3.actiivty.WatchDogService">
            <intent-filter>
                <action android:name="com.lypeer.aidl"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>

        </service>

五.在另外一個應用程式中繫結servie
上面的service就定義在com.betterda.test3這個包名的應用程式中,接下來我在com.betterda.test2這個包名的應用程式中通過bindService來啟動WatchDogService,然後呼叫test介面中定義的getString方法可以獲取到WatchDogService返回的資訊了,下面的程式碼就是bindservice

 Intent intent = new Intent();
        intent.setAction("com.lypeer.aidl");
        intent.setPackage("com.betterda.test3");
        if (!isBind) {
            //因為是在另外一個程式的servie,所以只能通過action和package來繫結servie
            bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        }

  private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            isBind = true;
            //繫結成功以後,會返回在Service的onbind方法中返回的binder物件,我們在WatchDogService的onbind方法中返回就是new MyBind(),它是test.Stub類
            //所以我們在這裡可以得到Stub的Proxy物件
            mTest = test.Stub.asInterface(service);

            try {
                //通過proxy的代理物件就可以呼叫getstring方法
                String string = mTest.getString("你好");
                Toast.makeText(MainActivity.this, string,0).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBind = false;
            Log.e(getLocalClassName(), "service disconnected");

        }
    };

在上面的程式碼中我們將繫結servive返回binder轉換來test.Stub的Proxy物件,然後才能呼叫在test介面中定義的方法,所以在這個com.betterda.test2應用程式也要定義一個同樣功能的aidl檔案,這個只要將com.betterda.test3中定義的aidl檔案拷貝過來,然後重新編譯就會自定生成了,執行com.betterda.test2就可以看到getString返回:遠端服務返回的資料:你好

六.總結
想要在程序間通訊使用都是Binder機制,aidl和bindService就為了方便開發者在自己的應用程式中使用Binder機制來通訊,bindService就是代替了ServiceManager的addService來向Binder驅動註冊服務.