知識點-----AIDL(二)簡單的aidl實現,自定義實體類

服務端

1、創建實體類:如BookBean,且BookBean要實現Parcelable接口,且要手動添加readFromParcel方法(不然只支持 in 的定向tag)

/**
 * 實現序列化的實體類
 * <p>
 * 序列化:由於不同的進程有着不同的內存區域,且相互之間不能直接訪問,
 * 所以我們必須將要傳輸的數據轉化爲能夠在內存之間流通的形式,這個轉換的過程就是序列化和反序列化
 */
public class BookBean implements Parcelable {

    private String name;
    private int price;

    protected BookBean(Parcel in) {
        name = in.readString();
        price = in.readInt();
    }

    public BookBean() {
    }

    public BookBean(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public static final Creator<BookBean> CREATOR = new Creator<BookBean>() {
        @Override
        public BookBean createFromParcel(Parcel in) {
            return new BookBean(in);
        }

        @Override
        public BookBean[] newArray(int size) {
            return new BookBean[size];
        }
    };

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "BookBean{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(price);
    }

    /**
     * 該方法不是Parcelable自動生成的,需要自己手動添加,
     * 如果不添加,則在使用AIDL時只支持 in 的定向tag
     * 如果添加了,則支持 in、out、inout
     *
     * @param dest 參數是一個Parcel,用它來存儲與傳輸數據
     */
    public void readFromParcel(Parcel dest) {
        name = dest.readString();
        price = dest.readInt();
    }

}

2、修改gradle:修改項目內部gradle,在android{} 裏添加設置代碼路徑,在AS中默認的java代碼路徑是java包目錄下,這樣aidl包下的java代碼系統就會找不到,會包Symbol not found

 

android {
    defaultConfig {……}
    buildTypes {……}

    //在AS中默認的java代碼路徑是java包目錄下,這樣aidl包下的java代碼系統就會找不到,會包Symbol not found
    sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src/main/aidl']
        }
    }
}

3、創建AIDL文件(需要寫兩個):,一個是BookBean.aidl,作用是把BookBean.java代碼引進aidl,以讓其他aidl文件可以訪問BookBean.java。另一個是具體的對外接口,如IBookManager.aidl

第一個aidl文件:

// Book.aidl
//第一類AIDL文件
//這個文件的作用是引入了一個序列化對象 Book 供其他的AIDL文件使用
//注意:BookBean.aidl與BookBean.java的包名應當是一樣的
package bai.bai.bai.demoaidlservice;

//注意 parcelable 必須是小寫
parcelable BookBean;

第二個aidl文件:

// BookManager.aidl
//第二類AIDL文件
//作用是定義方法接口
package bai.bai.bai.demoaidlservice;

//導入所需要使用的非默認支持數據類型的包
import bai.bai.bai.demoaidlservice.BookBean;

interface IBookManager {
    //所有的返回值前都不需要加任何東西,不管是什麼數據類型
    List<BookBean> getBooks();

    //Java基本類型以及String,CharSequence的 tag 默認且只能是 in
    //傳參時除了Java基本類型以及String,CharSequence之外的類型
    //都需要在前面加上定向tag,具體加什麼量需而定
    void addBook(in BookBean book);
}


4、創建服務:類似add功能的aidl裏服務

public class BookService extends Service {

    private List<BookBean> mBooks = new ArrayList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        mBooks.add(new BookBean("我是第一本", 11));
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    IBookManager.Stub mBinder = new IBookManager.Stub(){

        @Override
        public List<BookBean> getBooks() throws RemoteException {
            return mBooks;
        }

        @Override
        public void addBook(BookBean book) throws RemoteException {
            mBooks.add(book);
        }
    };

}

5、啓動服務,調用方法

public class BookActivity extends AppCompatActivity {

    private IBookManager mService;

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

        aboutService();

        findViewById(R.id.btn_book_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = ((EditText) findViewById(R.id.et_book_name)).getText().toString();
                int price = Integer.parseInt(((EditText) findViewById(R.id.et_book_price)).getText().toString());
                try {
                    mService.addBook(new BookBean(name, price));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

                try {
                    Log.d("baibai", "服務端:添加後的book列表長度:" + mService.getBooks().size());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

    }

    private void aboutService() {
        Intent intent = new Intent(this, BookService.class);
        bindService(intent, mConn, Context.BIND_AUTO_CREATE);
    }

    ServiceConnection mConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("baibai", "服務端:book 連接 Service 成功");
            mService = IBookManager.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
}

 

客戶端

 

1、創建實體類:要跟服務端的包名一樣(不然會找不到類)。
2、修改gradle:類似服務端(設置編譯代碼路徑)
3、aidl移植:把服務端的aidl文件複製到客戶端的aidl的包下。
4、啓動服務、調用方法:類似服務端

 

 

 

參考git代碼:服務端:https://github.com/baiyun1234/DemoAidlService

                     客戶端:https://github.com/baiyun1234/DemoAidlClient

參考網址:https://blog.csdn.net/guanhang89/article/details/51386404

                  https://blog.csdn.net/luoyanglizi/article/details/51980630

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