日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

十分钟让你明白AIDL

發(fā)布時間:2023/12/20 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 十分钟让你明白AIDL 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

我在[003]AIDL是什么中介紹的AIDL,但是好像還有朋友不明白問我,那我就來寫一個終極版的文章,讓你十分鐘徹底明白AIDL,以下代碼全為手寫。

目標(biāo)

Server進(jìn)程注冊一個Binder服務(wù)到SM,該Binder服務(wù)提供兩個接口:add和minus
Client 進(jìn)程通過SM獲得Binder服務(wù)的代理類BinderProxy,并調(diào)用兩個接口add,minus

1 沒有AIDL的世界

1.1 Server進(jìn)程

class CommandBinder extends Binder {@Overrideprotected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {if (code == 1) {int a = data.readInt();int b = data.readInt();reply.writeInt(a + b);return true;} else if (code == 2) {int a = data.readInt();int b = data.readInt();reply.writeInt(a + b);return true;}return super.onTransact(code, data, reply, flags);}}void main() {//注冊binder服務(wù)ServiceManager.addService("command", new CommandBinder());}

1.2 Client進(jìn)程

int add(int a, int b) {int code = 1;BinderProxy mClient = ServiceManager.getService("command");Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();mClient.transact(code, data, reply, 0);//flag設(shè)置成0,調(diào)用這個方法會跨進(jìn)程調(diào)用Binder服務(wù)類中onTransact方法int result = reply.readInt();return result;}int minus(int a, int b) {int code = 2;BinderProxy mClient = ServiceManager.getService("command");Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();mClient.transact(code, data, reply, 0);//flag設(shè)置成0,調(diào)用這個方法會跨進(jìn)程調(diào)用Binder服務(wù)類中onTransact方法int result = reply.readInt();return result;}

2 有AIDL的世界

AIDL文件

//aidlinterface ICommand {int add(int a, int b);int minus(int a, int b);}

2.1 Server進(jìn)程

與1.1中代碼比較,我們發(fā)現(xiàn),我們不是直接繼承Binder,而是繼承aidl文件自動生成ICommandBinder,我們只需專注寫add和minus接口的實(shí)現(xiàn),不需要在Binder類中的onTransact寫一堆if else代碼和Parcel.read write.

class ADILCommandBinder extends ICommandBinder {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int minus(int a, int b) {return a - b;}}void main() {//注冊binder服務(wù)ServiceManager.addService("command", new ADILCommandBinder());}

2.2 Client進(jìn)程

與1.2中代碼比較,我們發(fā)現(xiàn),我們不需要寫Parcel.read write和BinderProxy.transact,而是用BinderProxy對象構(gòu)造一個CommandBinderProxy對象,然后直接調(diào)用CommandBinderProxy的add和minus

int add(int a, int b) {BinderProxy mClient = ServiceManager.getService("command");return new CommandBinderProxy(mClient).add(a, b);}int minus(int a, int b) {BinderProxy mClient = ServiceManager.getService("command");return new CommandBinderProxy(mClient).minus(a, b);}

3 ADIL自動生成了什么代碼

生成了三個部分:ICommand,ICommandBinder,CommandBinderProxy

3.1 ICommand

看起來和aidl文件差不多

interface ICommand {int add(int a, int b);int minus(int a, int b);}

3.2 ICommandBinder

繼承于Binder,并實(shí)現(xiàn)ICommand,然后在onTransact方法中調(diào)用還沒有實(shí)現(xiàn)的add和minus方法

abstract public class ICommandBinder extends Binder implements ICommand {int add = 1;int minus = 2;@Overrideprotected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {if (code == 1) {int a = data.readInt();int b = data.readInt();reply.writeInt(add(a, b));return true;} else if (code == 2) {int a = data.readInt();int b = data.readInt();reply.writeInt(minus(a, b));return true;}return super.onTransact(code, data, reply, flags);}abstract public int add(int a, int b);abstract public int minus(int a, int b);}

3.3 CommandBinderProxy

對BinderProxy進(jìn)行封裝,把調(diào)用CommandBinderProxy的add轉(zhuǎn)化成Parcel.write,read和BinderProxy.transact代碼。

public class CommandBinderProxy implements ICommand {private BinderProxy remote;int add = 1;int minus = 2;public CommandBinderProxy(BinderProxy remote) {this.remote = remote;}@Overridepublic int add(int a, int b) {Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();remote.transact(add, data, reply, 0);int result = reply.readInt();return result;}@Overridepublic int minus(int a, int b) {int code = 2;Parcel data = Parcel.obtain();data.writeInt(a);data.writeInt(b);Parcel reply = Parcel.obtain();remote.transact(code, data, reply, 0);int result = reply.readInt();return result;}}

總結(jié)

看完應(yīng)該明白了AIDL作用主要有
a.偷懶,少很多代碼,尤其是你要寫上百個方法的時候,AIDL就派上大用場了。
b.讓服務(wù)端更專注接口的實(shí)現(xiàn),而減少犯錯誤的可能性
c.規(guī)范client端和server端的接口定義,有助于代碼的迭代

當(dāng)然這是我自己寫的偽代碼,AIDL真正生成的代碼比較復(fù)雜,但這些偽代碼就是AIDL核心點(diǎn)。

思考

oneway的這個語法對AIDL生成的代碼有什么影響,或者你們自己寫一下oneway的方法AIDL生成的偽代碼


? 回復(fù)「?籃球的大肚子」進(jìn)入技術(shù)群聊

回復(fù)「1024」獲取1000G學(xué)習(xí)資料

總結(jié)

以上是生活随笔為你收集整理的十分钟让你明白AIDL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。