AIDL基礎再接觸

AIDL基礎再接觸

這兩天再學習aidl的時候發現兩個進程怎麼都連接不上,於是看之前寫過一篇關於aidl的文章,發現沒什麼卵用!於是算是又學習了一篇發現了一些細節的東西必須要注意的,再寫一篇加深記憶!
關於aidl他喵的其實就是一個輔助生成binder類的工具!意思就是,你是用aidl其實就是想要生成一個binder類來進行通信,如果你足夠了解或者參考自動生成binder的話,不適用aidl也完全是可以的。

那先把話題扯到binder中:根據Android藝術探索一書中提到,binder是一個非常複雜的東西,建議小白對binder只需要瞭解和掌握基本的使用。binder可以理解爲一盒裝滿工具的工具箱。打比方說,這個工具箱在服務器那裏,而客戶端想用到裏面的工具,那怎麼辦?服務端把工具箱傳給客戶端唄。所以我認爲進程之間使用aidl的通信,本質上就是傳遞binder對象(工具箱)的通信。

那麼該如何傳遞這個binder對象?
對於服務端:必須要有binder類(工具箱)給服務端使用嘛,那怎麼傳遞給想要他的客戶端呢?使用Service,客戶端通過綁定服務端service能夠就能都返回這個binder對象了。那先在思路算是清晰了。(創建binder+創建Service)

那接下來服務端具體法你怎麼做:

服務端

1:創建binder類:
如果你還是小白,那就是用aidl來輔助我們把。首先創建aidl文件(andriudstudio能直接新建aidl文件),定義接口。
package com.example.administrator.aidlservice;
import com.example.administrator.aidlservice.Book;
interface IBookManager {

    Book getBook();
}

再貼一下我的類結構:
這裏寫圖片描述

注意:如果牽扯到自定義類的話,最好還是放到aidl文件夾下吧,並且也要創建這個自定義類的aidl文件,如圖所示Book.aidl;裏面的內容如下:

package com.example.administrator.aidlservice;

parcelable Book;

並且你還要留意一下IBookManager這個aidl文件中還需要import這個Book類的,即使已經在同一包下。如果你不把他放在同一個包下的話,在客戶端那邊就比較難保持結構一致了。
Book類放在了aidl目錄下會出現一個問題:無法查找到Book類,這應該是因爲默認是從java目錄下找類的吧,所以在grandle文件下配置一下,讓他也從aidl中尋找類。

sourceSets{
    mian{
        java.srcDirs=['src/main/java','src/mian/aidl'];
    }
}

這樣的話,你放在aidl的Book類也能找到了。
編譯一下,轉到project形式,在app/build/generated/source/aidl/debug下面是否有自動生成對應aidl的java類。有的話創建binder類就成功了。沒有的話就好好檢查一下。
關於生成的binder類在下編文章說下

2:創建service

package com.example.administrator.aidlservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class AIDLService extends Service {
    public AIDLService() {
    }
    IBookManager.Stub bind = new IBookManager.Stub() {
        @Override
        public Book getBook() throws RemoteException {
            return new Book("life",56);
        }
    };
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return bind;
    }
}

Stub是自動生成java類的內部類,創建binder對象重寫自定義的接口。在onBind中返回該binder對象。在註冊時候,加個action。最後別忘了開啓這個服務。

客戶端

把aidl的文件夾複製過來,保持結構、包名的一致。別忘了gandle中配置搜索的路徑,然後通過action,packge綁定服務。
package com.example.administrator.aidlclient;

import android.app.Service;
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.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.example.administrator.aidlservice.Book;
import com.example.administrator.aidlservice.IBookManager;

public class MainActivity extends AppCompatActivity {
    private IBookManager iBookManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setAction("aidlservice");
        intent.setPackage("com.example.administrator.aidlservice");
        ServiceConnection conn = new ServiceConnection() {

            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                iBookManager = IBookManager.Stub.asInterface(service);//這個方法很講究,放到下編講,哈哈
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
        boolean b = bindService(intent, conn, Service.BIND_AUTO_CREATE);
        Log.d("liangshijie", "onCreate: "+b);
    }

    public void bindBtn(View view) {
        try {
            Book book = iBookManager.getBook();
            Toast.makeText(this, book.toString(), Toast.LENGTH_SHORT).show();
        } catch (RemoteException e) {
            e.printStackTrace();
        }


    }
}

拿到了接口類型的對象(工具箱)也就能夠調用裏面定義的方法了(使用工具)。

那這篇就講到這,下編再細講一下,稍微努力接近原理一點

發佈了55 篇原創文章 · 獲贊 91 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章