轉(zhuǎn)http://blog.csdn.net/yulong0809/article/details/56841993。
最近一直在研究插件化的東西,我看了網(wǎng)上大多都是直接上來就開始講解原理然后寫個demo,這樣對于很多沒有入門的朋友不是很好的理解帆吻,下面我會通過自己的研究過程,一步一步循序漸進(jìn)的將插件化需要的知識點(diǎn)都梳理一遍及講解,其實(shí)學(xué)習(xí)插件化的好處并不全因?yàn)樗且婚T熱門的技術(shù)季二,插件化涉及的知識點(diǎn)很多,可以讓我們對android的理解及境界上都會有一個質(zhì)的飛躍揭措,在我將所有設(shè)計的知識點(diǎn)都大概講一遍后會用一個demo來實(shí)現(xiàn)插件化胯舷,里面將設(shè)計所有講過的知識。
插件化其實(shí)就是動態(tài)加載绊含,動態(tài)加載又包括了代碼加載和資源加載桑嘶。
插件化最早出現(xiàn)是因?yàn)?5535問題出現(xiàn)的,用于查分多個dex并動態(tài)加載dex來防止65535問題
現(xiàn)在很多公司用插件化來做模塊的動態(tài)加載躬充,這樣既能實(shí)現(xiàn)web端一樣的隨時更新逃顶,還能減少apk包的體積,其實(shí)就是加載一個未安裝的apk麻裳。
熱修復(fù)口蝠,熱修復(fù)其實(shí)也是動態(tài)加載原理
換膚,使用動態(tài)的資源加載可以實(shí)現(xiàn)換膚功能
還可以通過hook系統(tǒng)的一些類做一些你想做的壞事津坑。
任玉剛的:dynamic-load-apk妙蔗,這個項目使用的是一種代理的方式去實(shí)現(xiàn)?
https://github.com/singwhatiwanna/dynamic-load-apk
360的:DroidPlugin,這個項目是通過hook系統(tǒng)類來實(shí)現(xiàn)?
https://github.com/Qihoo360/DroidPlugin
阿里的:andfix,用于對方法的修復(fù)疆瑰,可以立即生效眉反,不支持資源及類替換?
https://github.com/alibaba/AndFix
騰訊的:tinker昙啄,除了不支持立即生效呵曹,全部支持
https://github.com/Tencent/tinker
美團(tuán)的:robust,不開源
如果要使用插件化來作為模塊化的話只怎,那么就需要解決兩個問題
代碼的加載,就是使用ClassLoader加載代碼
資源的加載疙教,使用AssetManager的隱藏方法梳杏,addAsssetPath方法加入一個資源路徑來獲取這個資源的Resource資源
還有一個問題就是對四大組件的生命周期管理
在了解插件化之前首先需要了解及掌握的知識點(diǎn)?
一韧拒、Binder機(jī)制?
二、代理模式十性,?
三叛溢、反射?
四、類加載及dex加載?
五劲适、應(yīng)用啟動過程及類加載過程?
六楷掉、實(shí)現(xiàn)插件化完整demo及思路分析?
Binder機(jī)制:
其實(shí)Binder看你怎么去理解霞势,如果從代碼角度的話他是一個類烹植,如果從硬件角度的話他是一個驅(qū)動,如果從IPC角度的話他是一種通信機(jī)制愕贡,是framework層的各種ServiceManager的鏈接橋梁草雕,?
我們知道我們平時使用的系統(tǒng)服務(wù)對象其實(shí)都是系統(tǒng)的,他們存在的進(jìn)程和我們的應(yīng)用并不在一個進(jìn)程中,但是為什么我們能直接使用呢颂鸿?其實(shí)就是因?yàn)锽inder的存在促绵,跨進(jìn)程通信攒庵,再說大白話一點(diǎn)就是使用了我們經(jīng)常說的aidl嘴纺,Binder很復(fù)雜,這里只是為了插件化做鋪墊浓冒,想深入理解請自行查閱資料栽渴。
進(jìn)程間通信過程
1.首先客戶端要鏈接服務(wù)端
2.然后服務(wù)端會返回一個客戶端的對象(代理對象)
3.然后客戶端使用這個代理對象其中的方法時,系統(tǒng)會先調(diào)用服務(wù)端的方法稳懒,然后將運(yùn)算的結(jié)果返回給客戶端(要知道其實(shí)并不是用了這個對象的方法闲擦,而是去服務(wù)端里運(yùn)算,然后在返回給客戶端的)
我們通過自己寫一個aidl场梆,然后和系統(tǒng)的源碼進(jìn)行對比
//我們自己寫的aidl的接口
//IMyAidlInterface.aidl
package com.huanju.chajianhuatest;
import com.huanju.chajianhuatest.aidlmode.TestBean;
interface IMyAidlInterface {
? ? /**
? ? * Demonstrates some basic types that you can use as parameters
? ? * and return values in AIDL.
? ? */
? ? void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
? ? ? ? ? ? double aDouble, String aString);
? ? String getS(in TestBean s);
? ? TestBean getInfoBean(out TestBean b);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
系統(tǒng)會幫我們自動創(chuàng)建一個IMyAidlInterface.java的文件墅冷,我們?nèi)タ纯?/p>
>
package com.huanju.chajianhuatest;
public interface IMyAidlInterface extends android.os.IInterface {
? ? public static abstract class Stub extends android.os.Binder implements com.huanju.chajianhuatest.IMyAidlInterface {
? ? ? ? private static final java.lang.String DESCRIPTOR = "com.huanju.chajianhuatest.IMyAidlInterface";
? ? ? ? public Stub() {
? ? ? ? ? ? this.attachInterface(this, DESCRIPTOR);
? ? ? ? }
? ? ? ? public static com.huanju.chajianhuatest.IMyAidlInterface asInterface(android.os.IBinder obj) {
? ? ? ? ? ? if ((obj == null)) {
? ? ? ? ? ? ? ? return null;
? ? ? ? ? ? }
? ? ? ? ? ? android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
? ? ? ? ? ? if (((iin != null) && (iin instanceof com.huanju.chajianhuatest.IMyAidlInterface))) {
? ? ? ? ? ? ? ? return ((com.huanju.chajianhuatest.IMyAidlInterface) iin);
? ? ? ? ? ? }
? ? ? ? ? ? return new com.huanju.chajianhuatest.IMyAidlInterface.Stub.Proxy(obj);
? ? ? ? }
? ? ? ? @Override
? ? ? ? public android.os.IBinder asBinder() {
? ? ? ? ? ? return this;
? ? ? ? }
? ? ? ? @Override
? ? ? ? public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
? ? ? ? ? ? switch (code) {
? ? ? ? ? ? ? ? case INTERFACE_TRANSACTION: {
? ? ? ? ? ? ? ? ? ? reply.writeString(DESCRIPTOR);
? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? case TRANSACTION_basicTypes: {
? ? ? ? ? ? ? ? ? ? data.enforceInterface(DESCRIPTOR);
? ? ? ? ? ? ? ? ? ? int _arg0;
? ? ? ? ? ? ? ? ? ? _arg0 = data.readInt();
? ? ? ? ? ? ? ? ? ? long _arg1;
? ? ? ? ? ? ? ? ? ? _arg1 = data.readLong();
? ? ? ? ? ? ? ? ? ? boolean _arg2;
? ? ? ? ? ? ? ? ? ? _arg2 = (0 != data.readInt());
? ? ? ? ? ? ? ? ? ? float _arg3;
? ? ? ? ? ? ? ? ? ? _arg3 = data.readFloat();
? ? ? ? ? ? ? ? ? ? double _arg4;
? ? ? ? ? ? ? ? ? ? _arg4 = data.readDouble();
? ? ? ? ? ? ? ? ? ? java.lang.String _arg5;
? ? ? ? ? ? ? ? ? ? _arg5 = data.readString();
? ? ? ? ? ? ? ? ? ? this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
? ? ? ? ? ? ? ? ? ? reply.writeNoException();
? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? case TRANSACTION_getS: {
? ? ? ? ? ? ? ? ? ? data.enforceInterface(DESCRIPTOR);
? ? ? ? ? ? ? ? ? ? com.huanju.chajianhuatest.aidlmode.TestBean _arg0;
? ? ? ? ? ? ? ? ? ? if ((0 != data.readInt())) {
? ? ? ? ? ? ? ? ? ? ? ? _arg0 = com.huanju.chajianhuatest.aidlmode.TestBean.CREATOR.createFromParcel(data);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? _arg0 = null;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? java.lang.String _result = this.getS(_arg0);
? ? ? ? ? ? ? ? ? ? reply.writeNoException();
? ? ? ? ? ? ? ? ? ? reply.writeString(_result);
? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? case TRANSACTION_getInfoBean: {
? ? ? ? ? ? ? ? ? ? data.enforceInterface(DESCRIPTOR);
? ? ? ? ? ? ? ? ? ? com.huanju.chajianhuatest.aidlmode.TestBean _arg0;
? ? ? ? ? ? ? ? ? ? _arg0 = new com.huanju.chajianhuatest.aidlmode.TestBean();
? ? ? ? ? ? ? ? ? ? com.huanju.chajianhuatest.aidlmode.TestBean _result = this.getInfoBean(_arg0);
? ? ? ? ? ? ? ? ? ? reply.writeNoException();
? ? ? ? ? ? ? ? ? ? if ((_result != null)) {
? ? ? ? ? ? ? ? ? ? ? ? reply.writeInt(1);
? ? ? ? ? ? ? ? ? ? ? ? _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? reply.writeInt(0);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if ((_arg0 != null)) {
? ? ? ? ? ? ? ? ? ? ? ? reply.writeInt(1);
? ? ? ? ? ? ? ? ? ? ? ? _arg0.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? reply.writeInt(0);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return super.onTransact(code, data, reply, flags);
? ? ? ? }
? ? ? ? private static class Proxy implements com.huanju.chajianhuatest.IMyAidlInterface {
? ? ? ? ? ? private android.os.IBinder mRemote;
? ? ? ? ? ? Proxy(android.os.IBinder remote) {
? ? ? ? ? ? ? ? mRemote = remote;
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public android.os.IBinder asBinder() {
? ? ? ? ? ? ? ? return mRemote;
? ? ? ? ? ? }
? ? ? ? ? ? public java.lang.String getInterfaceDescriptor() {
? ? ? ? ? ? ? ? return DESCRIPTOR;
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException {
? ? ? ? ? ? ? ? android.os.Parcel _data = android.os.Parcel.obtain();
? ? ? ? ? ? ? ? android.os.Parcel _reply = android.os.Parcel.obtain();
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? _data.writeInterfaceToken(DESCRIPTOR);
? ? ? ? ? ? ? ? ? ? _data.writeInt(anInt);
? ? ? ? ? ? ? ? ? ? _data.writeLong(aLong);
? ? ? ? ? ? ? ? ? ? _data.writeInt(((aBoolean) ? (1) : (0)));
? ? ? ? ? ? ? ? ? ? _data.writeFloat(aFloat);
? ? ? ? ? ? ? ? ? ? _data.writeDouble(aDouble);
? ? ? ? ? ? ? ? ? ? _data.writeString(aString);
? ? ? ? ? ? ? ? ? ? mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
? ? ? ? ? ? ? ? ? ? _reply.readException();
? ? ? ? ? ? ? ? } finally {
? ? ? ? ? ? ? ? ? ? _reply.recycle();
? ? ? ? ? ? ? ? ? ? _data.recycle();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public java.lang.String getS(com.huanju.chajianhuatest.aidlmode.TestBean s) throws android.os.RemoteException {
? ? ? ? ? ? ? ? android.os.Parcel _data = android.os.Parcel.obtain();
? ? ? ? ? ? ? ? android.os.Parcel _reply = android.os.Parcel.obtain();
? ? ? ? ? ? ? ? java.lang.String _result;
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? _data.writeInterfaceToken(DESCRIPTOR);
? ? ? ? ? ? ? ? ? ? if ((s != null)) {
? ? ? ? ? ? ? ? ? ? ? ? _data.writeInt(1);
? ? ? ? ? ? ? ? ? ? ? ? s.writeToParcel(_data, 0);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? _data.writeInt(0);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? mRemote.transact(Stub.TRANSACTION_getS, _data, _reply, 0);
? ? ? ? ? ? ? ? ? ? _reply.readException();
? ? ? ? ? ? ? ? ? ? _result = _reply.readString();
? ? ? ? ? ? ? ? } finally {
? ? ? ? ? ? ? ? ? ? _reply.recycle();
? ? ? ? ? ? ? ? ? ? _data.recycle();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return _result;
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public com.huanju.chajianhuatest.aidlmode.TestBean getInfoBean(com.huanju.chajianhuatest.aidlmode.TestBean b) throws android.os.RemoteException {
? ? ? ? ? ? ? ? android.os.Parcel _data = android.os.Parcel.obtain();
? ? ? ? ? ? ? ? android.os.Parcel _reply = android.os.Parcel.obtain();
? ? ? ? ? ? ? ? com.huanju.chajianhuatest.aidlmode.TestBean _result;
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? _data.writeInterfaceToken(DESCRIPTOR);
? ? ? ? ? ? ? ? ? ? mRemote.transact(Stub.TRANSACTION_getInfoBean, _data, _reply, 0);
? ? ? ? ? ? ? ? ? ? _reply.readException();
? ? ? ? ? ? ? ? ? ? if ((0 != _reply.readInt())) {
? ? ? ? ? ? ? ? ? ? ? ? _result = com.huanju.chajianhuatest.aidlmode.TestBean.CREATOR.createFromParcel(_reply);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? _result = null;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if ((0 != _reply.readInt())) {
? ? ? ? ? ? ? ? ? ? ? ? b.readFromParcel(_reply);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? } finally {
? ? ? ? ? ? ? ? ? ? _reply.recycle();
? ? ? ? ? ? ? ? ? ? _data.recycle();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return _result;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
? ? ? ? static final int TRANSACTION_getS = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
? ? ? ? static final int TRANSACTION_getInfoBean = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
? ? }
? ? public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
? ? public java.lang.String getS(com.huanju.chajianhuatest.aidlmode.TestBean s) throws android.os.RemoteException;
? ? public com.huanju.chajianhuatest.aidlmode.TestBean getInfoBean(com.huanju.chajianhuatest.aidlmode.TestBean b) throws android.os.RemoteException;
}
看著代碼好像很多,但是其實(shí)沒什么或油,我們分析一下結(jié)構(gòu)
1.我們根據(jù)上面的代碼寞忿,創(chuàng)建的類繼承了IInterface接口
2.內(nèi)部類Stub繼承Binder
3.看asInterface方法,判斷如果不是一個進(jìn)程會返回代理類
4.每個方法都對應(yīng)一個id顶岸,用于在跨進(jìn)程訪問時確定訪問的是哪個方法腔彰,通過transact方法再調(diào)用服務(wù)端的onTransact方法
我們再看一下系統(tǒng)的類叫编,就看我們最熟悉的ActivityManager,要知道ActivityManager其實(shí)是ActivityManagerService在我們進(jìn)程中的一個代理包裝類霹抛,他內(nèi)部全部使用 ActivityManagerNative.getDefault()去進(jìn)程操作搓逾,那么我么直接看 ActivityManagerNative的部分代碼
1.asInterface
? ? /** {@hide} */
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
? ? /**
? ? * Cast a Binder object into an activity manager interface, generating
? ? * a proxy if needed.
? ? */
? ? static public IActivityManager asInterface(IBinder obj) {
? ? ? ? if (obj == null) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? IActivityManager in =
? ? ? ? ? ? (IActivityManager)obj.queryLocalInterface(descriptor);
? ? ? ? if (in != null) {
? ? ? ? ? ? return in;
? ? ? ? }
? ? ? ? return new ActivityManagerProxy(obj);
? ? }
2.onTransact
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
? ? ? ? throws RemoteException {
? ? switch (code) {
? ? case START_ACTIVITY_TRANSACTION:
? ? {
? ? ? ? data.enforceInterface(IActivityManager.descriptor);
? ? ? ? IBinder b = data.readStrongBinder();
? ? ? ? IApplicationThread app = ApplicationThreadNative.asInterface(b);
? ? ? ? String callingPackage = data.readString();
? ? ? ? Intent intent = Intent.CREATOR.createFromParcel(data);
? ? ? ? String resolvedType = data.readString();
? ? ? ? IBinder resultTo = data.readStrongBinder();
? ? ? ? String resultWho = data.readString();
? ? ? ? int requestCode = data.readInt();
? ? ? ? int startFlags = data.readInt();
? ? ? ? ProfilerInfo profilerInfo = data.readInt() != 0
? ? ? ? ? ? ? ? ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
? ? ? ? Bundle options = data.readInt() != 0
? ? ? ? ? ? ? ? ? Bundle.CREATOR.createFromParcel(data) : null;
? ? ? ? int result = startActivity(app, callingPackage, intent, resolvedType,
? ? ? ? ? ? ? ? resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
? ? ? ? reply.writeNoException();
? ? ? ? reply.writeInt(result);
? ? ? ? return true;
? ? }
代碼太多我們就看這兩個就好了,有沒有感覺很熟悉杯拐,和我們自己寫的aidl幾乎沒有區(qū)別霞篡,他雖然叫做ActivityManagerNative,其實(shí)他就是我們自己寫的aidl里的內(nèi)部類Stub端逼。
下面我們分析一下aidl的運(yùn)行過程
我們直接看如果是遠(yuǎn)程的話返回了代理對象寇损,我們看代理對象的方法,這個方法就是aidl結(jié)果定義的方法裳食,看他怎么實(shí)現(xiàn)的?
>
@Override
? ? ? ? public com.huanju.chajianhuatest.aidlmode.TestBean getInfoBean(com.huanju.chajianhuatest.aidlmode.TestBean b) throws android.os.RemoteException {
? ? ? ? ? ? android.os.Parcel _data = android.os.Parcel.obtain();
? ? ? ? ? ? android.os.Parcel _reply = android.os.Parcel.obtain();
? ? ? ? ? ? com.huanju.chajianhuatest.aidlmode.TestBean _result;
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? _data.writeInterfaceToken(DESCRIPTOR);
? ? ? ? ? ? ? ? mRemote.transact(Stub.TRANSACTION_getInfoBean, _data, _reply, 0);
? ? ? ? ? ? ? ? _reply.readException();
? ? ? ? ? ? ? ? if ((0 != _reply.readInt())) {
? ? ? ? ? ? ? ? ? ? _result = com.huanju.chajianhuatest.aidlmode.TestBean.CREATOR.createFromParcel(_reply);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? _result = null;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if ((0 != _reply.readInt())) {
? ? ? ? ? ? ? ? ? ? b.readFromParcel(_reply);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } finally {
? ? ? ? ? ? ? ? _reply.recycle();
? ? ? ? ? ? ? ? _data.recycle();
? ? ? ? ? ? }
? ? ? ? ? ? return _result;
? ? ? ? }
? ? }
客戶端發(fā)起請求
1.首先創(chuàng)建輸出類型data
2.創(chuàng)建接受類型reply
3.創(chuàng)建需要的參數(shù)
4.將參數(shù)寫入data中
5.發(fā)起遠(yuǎn)程調(diào)用矛市,當(dāng)前線程掛起調(diào)用mRemote.transact()方法,這個方法的實(shí)現(xiàn)在Binder中诲祸,他會調(diào)用服務(wù)端的onTransact方法浊吏,直到有返回結(jié)果
6.從_result中取回返回結(jié)果_result
服務(wù)端接到請求會走到onTransact方法,這個方法運(yùn)行在服務(wù)端的Binder線程池中,我們再看看怎么實(shí)現(xiàn)的
>
? case TRANSACTION_getInfoBean: {
? ? ? ? ? ? ? ? data.enforceInterface(DESCRIPTOR);
? ? ? ? ? ? ? ? com.huanju.chajianhuatest.aidlmode.TestBean _arg0;
? ? ? ? ? ? ? ? _arg0 = new com.huanju.chajianhuatest.aidlmode.TestBean();
? ? ? ? ? ? ? ? com.huanju.chajianhuatest.aidlmode.TestBean _result = this.getInfoBean(_arg0);
? ? ? ? ? ? ? ? reply.writeNoException();
? ? ? ? ? ? ? ? if ((_result != null)) {
? ? ? ? ? ? ? ? ? ? reply.writeInt(1);
? ? ? ? ? ? ? ? ? ? _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? reply.writeInt(0);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if ((_arg0 != null)) {
? ? ? ? ? ? ? ? ? ? reply.writeInt(1);
? ? ? ? ? ? ? ? ? ? _arg0.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? reply.writeInt(0);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
1.通過id確定訪問哪個方法
2.然后從目標(biāo)參數(shù)data取出需要的參數(shù)
3.然后調(diào)用請求的相應(yīng)方法
4.將返回值寫入reply
5.返回true救氯,這里需要說一下找田,如果返回false,代表客戶端訪問失敗着憨,我們實(shí)際當(dāng)中可根據(jù)這個特性來做遠(yuǎn)程的校檢墩衙,畢竟我們的遠(yuǎn)程方法并是不想讓任何人都可以訪問的。?
甲抖,通過id確定訪問哪個方法漆改,然后從目標(biāo)參數(shù)data取出需要的參數(shù),然后調(diào)用相應(yīng)方法准谚,將返回值寫入reply挫剑,
好了,到這里Binder的通信過程就完了柱衔,其實(shí)我們看到了只要我們理解了我們自己寫的aidl的流程及原理樊破,那么系統(tǒng)層的通信也是這樣的。下一篇我們繼續(xù)說代理模式及反射唆铐。