第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

如何理解Android中的AIDL?

如何理解Android中的AIDL?

查看完整描述

1 回答

已采納
?
這個(gè)名字沒(méi)人起

TA貢獻(xiàn)12條經(jīng)驗(yàn) 獲得超7個(gè)贊

我們就看看IMyInterface.Stub吧:

public static abstract class Stub extends android.os.Binder implements aidl.IMyInterface {
..........
}

可以看到,Stub是IMyInterface中的一個(gè)靜態(tài)抽象類,繼承了Binder,并且實(shí)現(xiàn)了IMyInterface接口。這也就解釋了我們定義IMyInterface.Stub的時(shí)候?yàn)槭裁葱枰獙?shí)現(xiàn)IMyInterface中的方法了,也說(shuō)明了為什么我們可以把IMyInterface.Stub向上轉(zhuǎn)型成IBinder了。

Activity中的IMyInterface?
在Activity中,通過(guò)ServiceConnection連接MyService并成功回調(diào)onServiceConnected中我們把傳回來(lái)的IBinder通過(guò)IMyInterface.Stub.asInterface(service)轉(zhuǎn)換成為IMyInterface,那就來(lái)看看這里是如何轉(zhuǎn)換的吧:

public static abstract class Stub extends android.os.Binder implements aidl.IMyInterface {

..........

public static aidl.IMyInterface asInterface(android.os.IBinder obj) {
? ?if ((obj == null)) {
? ? ? ?return null;
? ?}
? ?
? ?android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
? ?if (((iin != null) && (iin instanceof aidl.IMyInterface))) {
? ? ? ?return ((aidl.IMyInterface) iin);
? ?}
? ?return new aidl.IMyInterface.Stub.Proxy(obj);
}
}

首先,我們因該明白的是,傳回來(lái)的IBinder就是我們?cè)赟ervice的onBind( )方法所return的IBinder,然后我們調(diào)用Stub中的靜態(tài)方法asInterface并把返回來(lái)的IBinder當(dāng)參數(shù)傳進(jìn)去。?
在asInterface方法中,首先判斷了傳進(jìn)來(lái)的IBinder是不是null,如果為null就返回一個(gè)null;接著就判斷傳進(jìn)來(lái)的IBinder是不是就在當(dāng)前進(jìn)程里面,如果是的話就直接返回IMyInterface,不是的話就返回IMyInterface.Stub.Proxy(obj)。這里我覺(jué)得需要明白的是:直接返回的IMyInterface是實(shí)現(xiàn)了定義的接口方法getInfor的。因?yàn)樵贗MyInterface.Stub中所實(shí)現(xiàn)的。當(dāng)然如果是在同一進(jìn)程中,那么我們調(diào)用IMyInterface的方法時(shí)就是在本地調(diào)用方法,直接調(diào)用就可以了。

如果沒(méi)在同一進(jìn)程,就會(huì)返回IMyInterface.Stub.Proxy(obj):

private static class Proxy implements aidl.IMyInterface {
? ? ? ?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 java.lang.String getInfor(java.lang.String 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);
? ? ? ? ? ? ? ?_data.writeString(s);
? ? ? ? ? ? ? //傳送數(shù)據(jù)到遠(yuǎn)程的
? ? ? ? ? ? ? ?mRemote.transact(Stub.TRANSACTION_getInfor, _data, _reply, 0);
? ? ? ? ? ? ? ?_reply.readException();
? ? ? ? ? ? ?//接受從遠(yuǎn)端傳回的數(shù)據(jù)
? ? ? ? ? ? ? ?_result = _reply.readString();
? ? ? ? ? ?} finally {
? ? ? ? ? ? ? ?_reply.recycle();
? ? ? ? ? ? ? ?_data.recycle();
? ? ? ? ? ?}
? ? ? ? ? ?return _result;
? ? ? ?}
? }
? ?static final int TRANSACTION_getInfor = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}

在Proxy中,我們首先把Service連接成功返回的IBinder它的內(nèi)部變量mRemote,這里在提一下,這里得IBinder還是是MyService中onBind所返回的。然后,當(dāng)我們調(diào)用IMyInterface的方法的時(shí)候,其實(shí)就是調(diào)用的Proxy的方法了,這也是為什么這個(gè)類叫做Porxy的原因了。

當(dāng)調(diào)用IMyInterface.getInfor(String s) ,我們就看Proxy中的getInfor,先獲取了兩個(gè)Parcel對(duì)象 _data、_data,從變量名就可以看出,一個(gè)是傳送數(shù)據(jù)的,另一個(gè)則是接受返回?cái)?shù)據(jù)的。接著,向_data中寫(xiě)入了DESCRIPTOR(也就是這個(gè)類的全名),再寫(xiě)入了方法參數(shù)。然后就到了最重要的一步了,

mRemote.transact(Stub.TRANSACTION_getInfor, _data, _reply, 0);?
這里我們調(diào)用了IBinder的transact方法,來(lái)把數(shù)據(jù)傳給遠(yuǎn)端的服務(wù)器。然后在我們遠(yuǎn)程的MyService中,里面的Stub中就會(huì)回調(diào)onTransact()(因?yàn)槟惆褦?shù)據(jù)傳個(gè)遠(yuǎn)程的服務(wù),遠(yuǎn)端的服務(wù)收到數(shù)據(jù)也就回調(diào)了)

注意:這里是在遠(yuǎn)程的服務(wù)里調(diào)用的。

@Overridepublic
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_getInfor: {
? ? ? ? ? ?data.enforceInterface(DESCRIPTOR);
? ? ? ? ? ?java.lang.String _arg0;
? ? ? ? ? //取出參數(shù)
? ? ? ? ? ?_arg0 = data.readString();
? ? ? ? ? // 遠(yuǎn)程服務(wù)調(diào)用自己本地實(shí)現(xiàn)的方法獲取返回值
? ? ? ? ? ?java.lang.String _result = this.getInfor(_arg0);
? ? ? ? ? ?reply.writeNoException();
? ? ? ? ? //寫(xiě)入返回值
? ? ? ? ? ?reply.writeString(_result);
? ? ? ? ? ?return true;
? ? ? ?}
? ?}
? ?return super.onTransact(code, data, reply, flags);
}

onTransact方法是在Stub的內(nèi)部實(shí)現(xiàn)的。

先看一下它的四個(gè)參數(shù):?
code:每個(gè)方法都有一個(gè)int類型的數(shù)字用來(lái)區(qū)分(后面中的swicth),在我們例子中也就是我們Proxy中的Stub.TRANSACTION_getInfor。?
data:傳過(guò)來(lái)的數(shù)據(jù),其中包含我們的參數(shù),以及類的描述。?
reply:傳回的數(shù)據(jù),我們要寫(xiě)入是否發(fā)生了Exception,以及返回值?
flags:該方法是否有返回值 ,0表示有返回值。

調(diào)用onTransact就表示有數(shù)據(jù)傳來(lái),首先就會(huì)通過(guò)swicth判斷是哪個(gè)方法,然后取出方法參數(shù),調(diào)用本地實(shí)現(xiàn)的方法獲取返回值,寫(xiě)入返回值到reply。最后,返回true,才會(huì)把數(shù)據(jù)發(fā)送出去,發(fā)揮false就不會(huì)把結(jié)果返回給Activity了。這里也就是說(shuō),只有返回true,我們Proxy中才能接受從遠(yuǎn)端傳回的數(shù)據(jù)。

? ? ? //傳送數(shù)據(jù)到遠(yuǎn)程的
? ? ? ?mRemote.transact(Stub.TRANSACTION_getInfor, _data, _reply, 0)
? ? ? ?_reply.readException()
? ? ? //接受從遠(yuǎn)端傳回的數(shù)據(jù)
? ? ? ?_result = _reply.readString()

注意:Service也是把數(shù)據(jù)發(fā)送出來(lái),讓客戶端接受的。

Service發(fā)出了數(shù)據(jù),客戶端接收到了,就會(huì)一層一層返回去。所以,當(dāng)我們簡(jiǎn)單的調(diào)用IMyInterface的getInfor時(shí)候,先是Proxy的transact發(fā)送出數(shù)據(jù),然后服務(wù)端的onTransact接受并處理傳來(lái)的數(shù)據(jù),再把處理得到的數(shù)據(jù)寫(xiě)入返回值并發(fā)送給客戶端,客戶端讀取值后就成為調(diào)用方法的返回值返回了。


查看完整回答
反對(duì) 回復(fù) 2018-03-09
  • 1 回答
  • 0 關(guān)注
  • 904 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)