android開發中通過aidl實現遠端方法呼叫
阿新 • • 發佈:2019-01-27
在安卓開發過程中我們可能見過這樣的問題,就是在一個應用中呼叫另一個應用中的服務,並呼叫該服務中的方法。
我們可能對呼叫服務並不陌生,可是要執行服務中的方法,卻不能直接呼叫。因為兩個服務和呼叫它的程式屬於兩個應用,在不同的專案中,根本訪問不到。安卓在設計的時候也幫我們想到了這個問題,並設計了aidl,下面我們來看一下到底是怎麼使用的
- 建立服務,並配置意圖過濾器,可以讓其他程式通過隱式意圖呼叫服務,在服務中編寫需要被呼叫的方法
- 在android studio中可以直接建立一個aidl檔案,在eclipse中需要手動建立檔案,字尾名為.aidl,在裡面定義一個介面,書寫方法和在.java檔案中寫介面一樣。寫完之後開發工具會自動生成一個同名的java檔案。該檔案最好不要開啟,因為不需要修改。
- 在服務中建立一個子類用來呼叫需要被遠端呼叫的方法,該類繼承上一步生成類的一個子類Stub ,並在服務的onBind方法中返回該類的物件。同時
- 將aidl檔案複製到需要呼叫該服務的應用中,這裡需要注意兩個aidl檔案所在的包名必須相同。
- 在需要呼叫的服務的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中列印日誌。