插件化知識詳細(xì)分解及原理 之Binder機(jī)制

轉(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

目前比較火的熱修復(fù)框架:

阿里的:andfix,用于對方法的修復(fù)疆瑰,可以立即生效眉反,不支持資源及類替換?

https://github.com/alibaba/AndFix

騰訊的:tinker昙啄,除了不支持立即生效呵曹,全部支持

https://github.com/Tencent/tinker

美團(tuán)的:robust,不開源

如果要使用插件化來作為模塊化的話只怎,那么就需要解決兩個問題

代碼的加載,就是使用ClassLoader加載代碼

資源的加載疙教,使用AssetManager的隱藏方法梳杏,addAsssetPath方法加入一個資源路徑來獲取這個資源的Resource資源

還有一個問題就是對四大組件的生命周期管理

準(zhǔn)備:

在了解插件化之前首先需要了解及掌握的知識點(diǎn)?

一韧拒、Binder機(jī)制?

二、代理模式十性,?

三叛溢、反射?

四、類加載及dex加載?

五劲适、應(yīng)用啟動過程及類加載過程?

六楷掉、實(shí)現(xiàn)插件化完整demo及思路分析?

七、動態(tài)加載資源及解決資源沖突問題

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ù)說代理模式及反射唆铐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哲戚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子艾岂,更是在濱河造成了極大的恐慌顺少,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澳盐,死亡現(xiàn)場離奇詭異祈纯,居然都是意外死亡令宿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門腕窥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粒没,“玉大人,你說我怎么就攤上這事簇爆●桑” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵入蛆,是天一觀的道長响蓉。 經(jīng)常有香客問我,道長哨毁,這世上最難降的妖魔是什么枫甲? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮扼褪,結(jié)果婚禮上想幻,老公的妹妹穿的比我還像新娘。我一直安慰自己话浇,他們只是感情好脏毯,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著幔崖,像睡著了一般食店。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赏寇,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天吉嫩,我揣著相機(jī)與錄音,去河邊找鬼蹋订。 笑死率挣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的露戒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼捶箱,長吁一口氣:“原來是場噩夢啊……” “哼智什!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丁屎,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤荠锭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后晨川,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體证九,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡删豺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了愧怜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呀页。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拥坛,靈堂內(nèi)的尸體忽然破棺而出蓬蝶,到底是詐尸還是另有隱情,我是刑警寧澤猜惋,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布丸氛,位于F島的核電站,受9級特大地震影響著摔,放射性物質(zhì)發(fā)生泄漏缓窜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一谍咆、第九天 我趴在偏房一處隱蔽的房頂上張望雹洗。 院中可真熱鬧,春花似錦卧波、人聲如沸时肿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽螃成。三九已至,卻和暖如春查坪,著一層夾襖步出監(jiān)牢的瞬間寸宏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工偿曙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氮凝,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓望忆,卻偏偏與公主長得像罩阵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子启摄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 雖然跨進(jìn)程通信的內(nèi)在機(jī)制十分復(fù)雜稿壁。但是Android為我們提供了一套非常簡單的機(jī)制,讓我們僅需要很少的步驟就能完成...
    passerbywhu閱讀 650評論 0 0
  • 上篇文章介紹了IPC機(jī)制的基本概念以及簡單使用歉备,文章鏈接:Android 關(guān)于IPC機(jī)制的理解(一) 這篇文章主要...
    老實(shí)任閱讀 729評論 0 2
  • AIDL(Android Interface Definition Language)傅是,即Android接口定義語...
    小編閱讀 1,475評論 4 7
  • 早上練了半個多小時的口語跟讀聯(lián)系喧笔。以前總想著要快點(diǎn)結(jié)束帽驯,總是草草了事。但內(nèi)心總是有個聲音再說书闸,這種敷衍了事的事了行...
    小魚記事錄閱讀 289評論 0 0
  • 散上幾片 往事在杯中沉淀 青綠便誘惑著我們 細(xì)嚼每一滴清香 也不是茶葉的滋味 騰騰熱氣飄散的記憶 只在唇邊留下絲絲甜蜜
    茜茜核桃媽閱讀 229評論 0 0