十分钟让你明白AIDL
前言
我在[003]AIDL是什么中介紹的AIDL,但是好像還有朋友不明白問我,那我就來寫一個終極版的文章,讓你十分鐘徹底明白AIDL,以下代碼全為手寫。
目標
Server進程注冊一個Binder服務到SM,該Binder服務提供兩個接口:add和minus
Client 進程通過SM獲得Binder服務的代理類BinderProxy,并調用兩個接口add,minus
1 沒有AIDL的世界
1.1 Server進程
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服務ServiceManager.addService("command", new CommandBinder());}1.2 Client進程
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設置成0,調用這個方法會跨進程調用Binder服務類中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設置成0,調用這個方法會跨進程調用Binder服務類中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進程
與1.1中代碼比較,我們發現,我們不是直接繼承Binder,而是繼承aidl文件自動生成ICommandBinder,我們只需專注寫add和minus接口的實現,不需要在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服務ServiceManager.addService("command", new ADILCommandBinder());}2.2 Client進程
與1.2中代碼比較,我們發現,我們不需要寫Parcel.read write和BinderProxy.transact,而是用BinderProxy對象構造一個CommandBinderProxy對象,然后直接調用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,并實現ICommand,然后在onTransact方法中調用還沒有實現的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進行封裝,把調用CommandBinderProxy的add轉化成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;}}總結
看完應該明白了AIDL作用主要有
a.偷懶,少很多代碼,尤其是你要寫上百個方法的時候,AIDL就派上大用場了。
b.讓服務端更專注接口的實現,而減少犯錯誤的可能性
c.規范client端和server端的接口定義,有助于代碼的迭代
當然這是我自己寫的偽代碼,AIDL真正生成的代碼比較復雜,但這些偽代碼就是AIDL核心點。
思考
oneway的這個語法對AIDL生成的代碼有什么影響,或者你們自己寫一下oneway的方法AIDL生成的偽代碼
? 回復「?籃球的大肚子」進入技術群聊
回復「1024」獲取1000G學習資料
總結
以上是生活随笔為你收集整理的十分钟让你明白AIDL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看我如何抓取最新房价数据
- 下一篇: QT 快捷键 识别小写字母