Android Service詳解(五)---綁定服務BoundService詳解之AIDL的使用

Android Service詳解(五)---綁定服務BoundService詳解之AIDL的使用

這是第四篇文章主要講的是綁定服務BoundService之AIDL的使用
回顧:

一、什麼是AIDL

AIDL(Android Interface Definition Language)安卓接口定義語言


二、爲什麼使用AIDL呢?

如果將Service變成遠程Service的話,使用擴展的Binder進行通信會報錯:
這是由於在Bind Service按鈕的點擊事件裏面我們會讓MainActivity和MyService建立關聯,但是目前MyService已經是一個遠程Service了,Activity和Service運行在兩個不同的進程當中,這時就不能再使用傳統的建立關聯的方式,程序也就崩潰了。
那麼如何才能讓Activity與一個遠程Service建立關聯呢?這就要使用AIDL來進行跨進程通信了(IPC)。

三、使用步驟

1.創建一個服務重寫這四個方法
@Override
public void onCreate() {
    super.onCreate();
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public boolean onUnbind(Intent intent) {
    return super.onUnbind(intent);
}

@Override
public void onDestroy() {
    super.onDestroy();
}
2.在Mainactivity創建一個ServiceConnection類的對象並實現。
private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {

    }
};
其中onServiceConnected()方法是綁定成功後回調的方法
onServiceConnected()方法是綁定服務異常終止是調用的方法
3.進行綁定
Intent intent = new Intent(this, MyBoundService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
bindService是異步綁定
 bindService(Intent,ServiceConnection對象,常量)
第一個參數:Intent指示對應的Service對象
第二個參數:實現了 ServiceConnection接口的對象
第三個參數:Flags
在進行服務綁定時,其標誌位可以爲BIND_AUTO_CREATE、BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND等。
其中BIND_AUTO_CREATE表示當收到綁定請求時,如果服務尚未創建,則即刻創建,在系統內存不足,需要先銷燬優先級組件來釋放內存,且只有駐留該服務的進程成爲被銷燬對象時,服務纔可被銷燬;BIND_DEBUG_UNBIND通常用於調試場景中判斷綁定的服務是否正確,但其會引起內存泄漏,因此非調試目的不建議使用;BIND_NOT_FOREGROUND表示系統將阻止駐留該服務的進程具有前臺優先級,僅在後臺運行,該標誌位在Froyo中引入。
4.解除綁定
unbindService(conn);	

5.定義一個標誌  未綁定的時候不讓其綁定

6.建立一個AIDL文件


7.在AIDL文件中寫需要通信實現的業務方法
一個AIDL文件
不能有修飾符,類似接口的寫法
支持類型8種基本數據類型String, CharSequence,List<String>,Map,自定義類型
interface MyAidl {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
     void setString(String str);
     String desc();
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}
8.Rebuild工程
會自動生成一個文件切換到Project模式下可以看到


這個生成的類不要編輯
靜態的抽象類Stub(存根)類集成了Binder實定義的接口
Proxy代理的設計模式,工作,去除了我們需要通訊需要的操作

9.創建一個業務類實現Stub接口的方法,在這裏寫業務的實現方法
public class MyImpl extends MyAidl.Stub {
    private String str;
    @Override
    public void setString(String str) throws RemoteException {
        this.str = str;
    }

    @Override
    public String desc() throws RemoteException {
        return "這是傳遞來的數據"+str;
    }

    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

    }
}

10.在創建的服務類中的
@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
}
(修改前)
返回實現類
@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return new Impl();
}
(修改後)

11.在Activity中創建一個通用的接口
private IMyAidlInterface iMyAidlInterface;
在綁定成功後實例化
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
12.設置一個標記來判斷是否被綁定,並在綁定和解綁是更改數據
13.實例話後調用業務實現方法
private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
        Log.e("ceshi", "綁定");
        Log.e("ceshi", iMyAidlInterface.toString());
        myBound = true;
    }
14.點擊打印出的日誌如下



源碼會在下一篇博客一起更新


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