1. 程式人生 > >android開發中通過aidl實現遠端方法呼叫

android開發中通過aidl實現遠端方法呼叫

在安卓開發過程中我們可能見過這樣的問題,就是在一個應用中呼叫另一個應用中的服務,並呼叫該服務中的方法。

我們可能對呼叫服務並不陌生,可是要執行服務中的方法,卻不能直接呼叫。因為兩個服務和呼叫它的程式屬於兩個應用,在不同的專案中,根本訪問不到。安卓在設計的時候也幫我們想到了這個問題,並設計了aidl,下面我們來看一下到底是怎麼使用的

  1. 建立服務,並配置意圖過濾器,可以讓其他程式通過隱式意圖呼叫服務,在服務中編寫需要被呼叫的方法
  2. 在android studio中可以直接建立一個aidl檔案,在eclipse中需要手動建立檔案,字尾名為.aidl,在裡面定義一個介面,書寫方法和在.java檔案中寫介面一樣。寫完之後開發工具會自動生成一個同名的java檔案。該檔案最好不要開啟,因為不需要修改。
  3. 在服務中建立一個子類用來呼叫需要被遠端呼叫的方法,該類繼承上一步生成類的一個子類Stub ,並在服務的onBind方法中返回該類的物件。同時
  4. 將aidl檔案複製到需要呼叫該服務的應用中,這裡需要注意兩個aidl檔案所在的包名必須相同。
  5. 在需要呼叫的服務的activity中建立ServiceConnection物件,並實現其抽象方法。通過aidl名.Stub.asInterface(Ibinder物件);獲取到在服務中建立的子類物件,就可以操作遠端服務中的方法了。

下面我們來看個例子
服務端的服務配置如下

<service android:name="com.example.aidldy.myService"
>
<intent-filter><action android:name="com.zl.aidl.service"/></intent-filter> </service>

aidl檔案

package com.example.aidldy;
interface aaa{
    //暴露出該方法用於呼叫服務中的a()方法
    void toA();
}

服務對應的檔案

package com.example.aidldy;

import android.app.Service;
import android.content.Intent;
import
android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class myService extends Service { @Override public IBinder onBind(Intent arg0) { return new bb(); } public void a(){ Log.e("com.zl.aidl", "服務中方法被呼叫了"); } //繼承開發工具根據aidl檔案生成的類 class bb extends aaa.Stub{ @Override public void toA() throws RemoteException { a(); } } }

接下來在另一個應用的activity中呼叫,activity同樣需要有相同的aidl檔案,activity如下

package com.example.aidldemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;

import com.example.aidldy.aaa;

public class MainActivity extends Activity {

    aaa aa;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ServiceConnection connection = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName arg0) {

            }

            @Override
            public void onServiceConnected(ComponentName arg0, IBinder arg1) {
                aa = aaa.Stub.asInterface(arg1);
            }
        };

        Intent intent = new Intent();
        intent.setAction("com.zl.aidl.service");
        startService(intent);
        bindService(intent, connection, 0);

    }

    public void click(View v){
        try {
            aa.toA();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}

上面的click()方法為頁面上一個Button的回撥方法,當Button被點選的時候該方法就會被呼叫然後執行服務中的方法在LogCat中列印日誌。

一個小例子就完了,希望對閱讀本文章的朋友有所幫助。