Android開發的app,Android Binder—APP-framework(mRemote的前世今生)

 2023-11-19 阅读 42 评论 0

摘要:作者 |?開開向前沖地址 |?http://www.jianshu.com/p/72bc48d59f0e聲明 |?本文是 開開向前沖?原創,已獲授權發布,未經原作者允許請勿轉載Android開發的app、前言本文參考一個朋友兼同事ShadowN1ght的文章客戶端到驅動通信流程;用一個簡單的案例闡述了完整

作者 |?開開向前沖

地址 |?http://www.jianshu.com/p/72bc48d59f0e

聲明 |?本文是 開開向前沖?原創,已獲授權發布,未經原作者允許請勿轉載


Android開發的app、

前言

本文參考一個朋友兼同事ShadowN1ght的文章客戶端到驅動通信流程;用一個簡單的案例闡述了完整的Binder 通信過程;


Binder之于Android,猶如電話之于人類,都是用于傳遞信息;

android binder、

寫這篇文章前我醞釀了很久,不知道該何從下筆,文章寫了又刪,刪了又寫,因為始終感覺寫的有點雜,一不注意就丟失了主線;現在通過跟蹤一個完整的Binder調用來說明Binder IPC的過程——PowerManger調用isScreenOn();


分析

方案設計:Binder通信涉及APP層,framework層,Kernel層,雖然涉及的東西比較雜,但是都是代碼實現的,既然如此,我們都可以通過增加調試Log信息來跟蹤這個流程,本文的思路就是如此;

Android APP。

為了更好的理解 Binder 通信過程,你最好有一套完整的 Android 源碼,再配上一個代碼搜索神器 OpenGrok,如果你沒有 android源碼,不想自己搭建 OpenGrok 服務器,這里推薦一個公開的 Android Code In OpenGrok,只不過由于網速問題你可能得多花點時間等待;


1. APP——> framework
import com.example.bindservice.ProcessInfo;

public class MainActivity extends AppCompatActivity {
? ?String TAG = "Bindertest MainActivity";

? ?@Override
? ?protected void onCreate(Bundle savedInstanceState) {
? ? ? ?super.onCreate(savedInstanceState);
? ? ? ?setContentView(R.layout.activity_main);
? ? ? ?findViewById(R.id.mybtn).setOnClickListener(new View.OnClickListener() {
? ? ? ? ? ?@Override
? ? ? ? ? ?public void onClick(View v) {
? ? ? ? ? ? ? ?ProcessInfo processInfo = new ProcessInfo();
? ? ? ? ? ? ? ?processInfo.nativeSelfCall();
? ? ? ? ? ? ? ?PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
? ? ? ? ? ? ? ?Log.e(TAG,"App begin nativeCall");
? ? ? ? ? ? ? ?boolean bool = powerManager.isScreenOn();
? ? ? ? ? ? ? ?Log.e(TAG,"App end nativeCall");
? ? ? ? ? ? ? ?Log.e(TAG,"" + bool);
? ? ? ? ? ?}
? ? ? ?});
? ?}
}

Binder過程很簡單,就是調用了powerManager.isScreenOn();//Binder Call 代碼;
processInfo.nativeSelfCall()是自己添加的JNI,目的是向Binder Kernel中傳遞cmd,然后在Binder Kernel中根據cmd獲取到應用進程ID,過濾Log;這里暫時不說;


android.jar、/frameworks/base/core/java/android/os/PowerManager.java

@Deprecated
public boolean isScreenOn() {
? ?return isInteractive();
}

public boolean isInteractive() {
? ?try {
? ? ? ?return mService.isInteractive();
? ?} catch (RemoteException e) {
? ? ? ?return false;
? ?}
}

PowerManger.java中的isScreenOn最終會調用 mService.isInteractive();這里的mService是什么呢???

mService
final IPowerManager mService;
/**
* {@hide}
*/

public PowerManager(Context context, IPowerManager service, Handler handler) {
? ?mContext = context;
? ?mService = service;//mService初始化是在PowerManager構造方法中
? ?mHandler = handler;
}

mService 是IPowerManager 對象;這里根據名字我們就知道IPowerManager是通過AIDL生成的代碼,可以在Android Studio中查找;找到:
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/IPowerManager.java

------> IPowerManager.java——>Proxy
? ? ?@Override
? ? ?public boolean isInteractive() throws android.os.RemoteException {
? ? ? ? ? ?android.os.Parcel _data = android.os.Parcel.obtain();
? ? ? ? ? ?android.os.Parcel _reply = android.os.Parcel.obtain();
? ? ? ? ? ?boolean _result;
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?_data.writeInterfaceToken(DESCRIPTOR);
? ? ? ? ? ? ? ?mRemote.transact(Stub.TRANSACTION_isInteractive, _data, _reply, 0);//核心核心
? ? ? ? ? ? ? ?_reply.readException();
? ? ? ? ? ? ? ?_result = (0 != _reply.readInt());
? ? ? ? ? ?} finally {
? ? ? ? ? ? ? ?_reply.recycle();
? ? ? ? ? ? ? ?_data.recycle();
? ? ? ? ? ?}
? ? ? ? ? ?return _result;
? ? ? ?}

_data用于包裝客戶端數據,_reply用于從服務端獲取數據,mRemote是android.os.IBinder對象,DESCRIPTOR標識了IPowerManager ,DESCRIPTOR = "android.os.IPowerManager";TRANSACTION_isInteractive 是方法號,TRANSACTION_isInteractive = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11);_result即我們應用層得到的值,這里是根據reply獲取的值來賦值的;


這里我重點看看mRemote;

------> IPowerManager.java——>Proxy
? ? ? ?......
? ? ? ?private static class Proxy implements android.os.IPowerManager {
? ? ? ? ? ?private android.os.IBinder mRemote;

? ? ? ? ? ?Proxy(android.os.IBinder remote) {
? ? ? ? ? ? ? ?mRemote = remote;//賦值
? ? ? ? ? ?}

? ? ? ? ? ?@Override
? ? ? ? ? ?public android.os.IBinder asBinder() {
? ? ? ? ? ? ? ?return mRemote;
? ? ? ? ? ?}
? ? ? ? ? ?......
? ? ? ?}

Android。這里mRemote是在Proxy的構造方法中被調用,那Proxy是在什么地方調用呢?

------>IPowerManager.java——>Stub
? ? ? ?/**
? ? ? ? * Cast an IBinder object into an android.os.IPowerManager interface,
? ? ? ? * generating a proxy if needed.
? ? ? ? */

? ? ? ?public static android.os.IPowerManager asInterface(android.os.IBinder obj) {
? ? ? ? ? ?if ((obj == null)) {
? ? ? ? ? ? ? ?return null;
? ? ? ? ? ?}
? ? ? ? ? ?android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
? ? ? ? ? ?if (((iin != null) && (iin instanceof android.os.IPowerManager))) {
? ? ? ? ? ? ? ?return ((android.os.IPowerManager) iin);
? ? ? ? ? ?}
? ? ? ? ? ?return new android.os.IPowerManager.Stub.Proxy(obj);//調用Proxy構造函數
? ? ? ?}

這里IPowerManger.Stub asInterface在什么地方調用呢?asInterface返回的對象是IPowerManager對象;在Android Studio 查看該方法在那些地方被調用,你會發現有很對,但是我相信你會特別在ContextImpl的;
/frameworks/base/core/java/android/app/ContextImpl.java

------> ContextImpl.java
? ? ? ?registerService(POWER_SERVICE, new ServiceFetcher()
{
? ? ? ? ? ? ? ?public Object createService(ContextImpl ctx) {
? ? ? ? ? ? ? ? ? ?IBinder b = ServiceManager.getService(POWER_SERVICE);
? ? ? ? ? ? ? ? ? ?IPowerManager service = IPowerManager.Stub.asInterface(b);
? ? ? ? ? ? ? ? ? ?//調用IPowerManger.stub.asInterface,傳入的IBinder對象參數是從
? ? ? ? ? ? ? ? ? ?//ServiceManager.getService(POWER_SERVICE)獲取的
? ? ? ? ? ? ? ? ? ?if (service == null) {
? ? ? ? ? ? ? ? ? ? ? ?Log.wtf(TAG, "Failed to get power manager service.");
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ?return new PowerManager(ctx.getOuterContext(),
? ? ? ? ? ? ? ? ? ? ? ? ? ?service, ctx.mMainThread.getHandler())
;//返回PowerManager對象,
? ? ? ? ? ? ? ? ? ?//這里的service就是PowerManger類中的mService,
//我們在應用層調用的 ?(PowerManager) getSystemService(Context.POWER_SERVICE)
//得到的powerManger對象就是這里返回的new PowerManager,這部分代碼跟著邏輯就能看到;
? ? ? ? ? ? }});

看到registerService方法,我相信很多人都很熟悉,這里的service就是PowerManger類中的mService,
應用層調用的 ?(PowerManager) getSystemService(Context.POWER_SERVICE)得到的powerManger對象
就是這里返回的new PowerManager,順著Activity的getSystemService方法的邏輯看就會清楚;
PowerManager中的mService就是這里的service,通過 IPowerManager.Stub.asInterface(b)獲得;


IBinder b = ServiceManager.getService(POWER_SERVICE);
IPowerManager service = IPowerManager.Stub.asInterface(b);
這里真正開始接觸IBiner,這里做個標記,等會可能會回頭再來看

android singleInstance。

這里調用 IPowerManager.Stub.asInterface(b)的IBinder b參數是從ServiceManager.getService(POWER_SERVICE)獲取的,那這個IBinder b值是什么呢???(我這里先透露一下,IBinder b是一個BinderProxy對象


/frameworks/base/core/java/android/os/ServiceManager.java

------> ServiceManager.java
/**
? ? * Returns a reference to a service with the given name.
? ? *
? ? * @param name the name of the service to get
? ? * @return a reference to the service, or <code>null</code> if the service doesn't exist
? ? */

? ?public static IBinder getService(String name) {
? ? ? ?try {
? ? ? ? ? ?IBinder service = sCache.get(name);
? ? ? ? ? ?if (service != null) {
? ? ? ? ? ? ? ?return service;
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?return getIServiceManager().getService(name);//核心核心
? ? ? ? ? ?}
? ? ? ?} catch (RemoteException e) {
? ? ? ? ? ?Log.e(TAG, "error in getService", e);
? ? ? ?}
? ? ? ?return null;
? ?}

這里先從緩存中獲取IBinder,緩存中沒有則調用getIServiceManager().getService(name)獲取;

------> ServiceManager.java
? ?private static IServiceManager getIServiceManager()
{
? ? ? ?if (sServiceManager != null) {
? ? ? ? ? ?return sServiceManager;
? ? ? ?}
? ? ? ?// Find the service manager
? ? ? ?sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());//核心核心
? ? ? ?return sServiceManager;
? ?}

Android修改APP版本號、/frameworks/base/core/java/android/os/ServiceManagerNative.java
ServiceManagerNative.asInterface(BinderInternal.getContextObject())的參數為BinderInternal.getContextObject();

------> ServiceManagerNative.java
?static public IServiceManager asInterface(IBinder obj)
? ?
{
? ? ? ?if (obj == null) {
? ? ? ? ? ?return null;
? ? ? ?}
? ? ? ?IServiceManager in =
? ? ? ? ? ?(IServiceManager)obj.queryLocalInterface(descriptor);//如果沒有真正的跨進程通信,則從這里返回
? ? ? ?//Binder 類有實現,BinderProxy沒有實現queryLocalInterface方法;
? ? ? ?if (in != null) {
? ? ? ? ? ?return in;//判斷是否是真的跨進程,比如應用內部實現service,就沒真正跨進程,從這里返回;
? ? ? ?}
? ? ? ?return new ServiceManagerProxy(obj);//核心核心核心,跨進程
? ?}

使用OpenGrok搜索"implements IBinder",會發現Binder.java 文件中class Binder和
class BinderProxy兩個類實現了IBinder
;此處我先不確定queryLocalInterface是否是調用的這里;我們先確定
static public IServiceManager asInterface(IBinder obj)的參數IBinder obj;obj是ServiceManager.java中調用ServiceManagerNative.asInterface(BinderInternal.getContextObject())傳遞過來的,所以
obj = BinderInternal.getContextObject();我們看看ServiceManagerProxy的構造方法,會發現ServiceManagerProxy中
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
},即BinderInternal.getContextObject()的返回值將賦值給mRemote


/frameworks/base/core/java/com/android/internal/os/BinderInternal.java

------> BinderInternal.java
public static final native IBinder getContextObject();

這里使用JNI來獲取IBinder對象;根據Android JNI命名規則,我們知道getContextObject方法在android_util_Binder.cpp中實現;

------> android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = {
? ? /* name, signature, funcPtr */
? ?{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
? ?{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
? ?{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
? ?{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
? ?sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//ProcessState采用單列,整個應用只有一個實例
? ?return javaObjectForIBinder(env, b);//將native binder轉換為Java Binder對象,這里返回BinderProxy對象,下面會說明;
}

android binder機制原理、這里通過 ProcessState創建native IBinder對象;再調用javaObjectForIBinder將native Binder對象轉換成Java層的Binder對象;

------> ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)//caller 上面傳遞的值為null
{
? ?return getStrongProxyForHandle(0);//參數為0
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
? ?sp<IBinder> result;

? ?AutoMutex _l(mLock);

? ?handle_entry* e = lookupHandleLocked(handle);//此時handle=0

? ?if (e != NULL) {
? ? ? ?// We need to create a new BpBinder if there isn't currently one, OR we
? ? ? ?// are unable to acquire a weak reference on this current one. ?See comment
? ? ? ?// in getWeakProxyForHandle() for more info about this.
? ? ? ?IBinder* b = e->binder;
? ? ? ?if (b == NULL || !e->refs->attemptIncWeak(this)) {
? ? ? ? ? ?if (handle == 0) {
? ? ? ? ? ? ? ?// Special case for context manager...
? ? ? ? ? ? ? ?// The context manager is the only object for which we create
? ? ? ? ? ? ? ?// a BpBinder proxy without already holding a reference.
? ? ? ? ? ? ? ?// Perform a dummy transaction to ensure the context manager
? ? ? ? ? ? ? ?// is registered before we create the first local reference
? ? ? ? ? ? ? ?// to it (which will occur when creating the BpBinder).
? ? ? ? ? ? ? ?// If a local reference is created for the BpBinder when the
? ? ? ? ? ? ? ?// context manager is not present, the driver will fail to
? ? ? ? ? ? ? ?// provide a reference to the context manager, but the
? ? ? ? ? ? ? ?// driver API does not return status.
? ? ? ? ? ? ? ?//
? ? ? ? ? ? ? ?// Note that this is not race-free if the context manager
? ? ? ? ? ? ? ?// dies while this code runs.
? ? ? ? ? ? ? ?//
? ? ? ? ? ? ? ?// TODO: add a driver API to wait for context manager, or
? ? ? ? ? ? ? ?// stop special casing handle 0 for context manager and add
? ? ? ? ? ? ? ?// a driver API to get a handle to the context manager with
? ? ? ? ? ? ? ?// proper reference counting.

? ? ? ? ? ? ? ?Parcel data;
? ? ? ? ? ? ? ?status_t status = IPCThreadState::self()->transact(
? ? ? ? ? ? ? ? ? ? ? ?0, IBinder::PING_TRANSACTION, data, NULL, 0);
? ? ? ? ? ? ? ?if (status == DEAD_OBJECT)
? ? ? ? ? ? ? ? ? return NULL;
? ? ? ? ? ?}

? ? ? ? ? ?b = new BpBinder(handle); //創建BpBinder,即b = new BpBinder(0);
? ? ? ? ? ?e->binder = b;
? ? ? ? ? ?if (b) e->refs = b->getWeakRefs();
? ? ? ? ? ?result = b;//用new BpBinder(0)給result賦值,最后返回result
? ? ? ?} else {
? ? ? ? ? ?// This little bit of nastyness is to allow us to add a primary
? ? ? ? ? ?// reference to the remote proxy when this team doesn't have one
? ? ? ? ? ?// but another team is sending the handle to us.
? ? ? ? ? ?result.force_set(b);
? ? ? ? ? ?e->refs->decWeak(this);
? ? ? ?}
? ?}

? ?return result;//返回new BpBinder(0)
}

sp<IBinder> b = ProcessState::self()->getContextObject(NULL)返回的是new BpBinder(0);返回到android_os_BinderInternal_getContextObject方法中,接下來會調用javaObjectForIBinder方法;

------> javaObjectForIBinder
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
? ?if (val == NULL) return NULL;

? ?if (val->checkSubclass(&gBinderOffsets)) {
? ? ? ?// One of our own!
? ? ? ?jobject object = static_cast<JavaBBinder*>(val.get())->object();
? ? ? ?LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
? ? ? ?return object;
? ?}

? ?// For the rest of the function we will hold this lock, to serialize
? ?// looking/creation of Java proxies for native Binder proxies.
? ?AutoMutex _l(mProxyLock);

? ?// Someone else's... ?do we know about it?
? ?jobject object = (jobject)val->findObject(&gBinderProxyOffsets);//gBinderProxyOffsets很重要,
//gBinderProxyOffets在int_register_android_os_BinderProxy中初始化,指向Java層的BinderProxy(核心核心核心),
//int_register_android_os_BinderProxy在register_android_os_Binder中調用,register_android_os_Binder
//在開機過程中AndroidRuntime.startReg方法中被調用;
? ?if (object != NULL) {
? ? ? ?jobject res = jniGetReferent(env, object);
? ? ? ?if (res != NULL) {
? ? ? ? ? ?ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
? ? ? ? ? ?return res;
? ? ? ?}
? ? ? ?LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
? ? ? ?android_atomic_dec(&gNumProxyRefs);
? ? ? ?val->detachObject(&gBinderProxyOffsets);
? ? ? ?env->DeleteGlobalRef(object);
? ?}

? ?object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
? ?//gBinderProxyOffsets.mClass指向BinderProxy class,gBinderProxyOffsets.mConstructor指向BinderProxy構造方法;
? ?if (object != NULL) {
? ? ? ?LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
? ? ? ?// The proxy holds a reference to the native object.
? ? ? ?env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());//val是BpBinder,
? ? ? ?//這里利用JNI 調用java將讀到的BpBinder 對象val存入BinderProxy的mObject變量中
? ? ? ?val->incStrong((void*)javaObjectForIBinder);
? ? ? ?// The native object needs to hold a weak reference back to the
? ? ? ?// proxy, so we can retrieve the same proxy if it is still active.
? ? ? ?jobject refObject = env->NewGlobalRef(
? ? ? ? ? ? ? ?env->GetObjectField(object, gBinderProxyOffsets.mSelf));
? ? ? ?val->attachObject(&gBinderProxyOffsets, refObject,
? ? ? ? ? ? ? ?jnienv_to_javavm(env), proxy_cleanup);
? ? ? ?// Also remember the death recipients registered on this proxy
? ? ? ?sp<DeathRecipientList> drl = new DeathRecipientList;
? ? ? ?drl->incStrong((void*)javaObjectForIBinder);
? ? ? ?env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
? ? ? ?// Note that a new object reference has been created.
? ? ? ?android_atomic_inc(&gNumProxyRefs);
? ? ? ?incRefsCreated(env);
? ?}
? ?return object;//返回Java BinderProxy對象
}

所以前面BinderInternal.java 中 getContextObject()方法會返回一個BinderProxy對象;并將獲取到的BpBinder對象存入Java層BinderProxy類的mObject變量中;


是不是有點蒙圈了,休息休息休息休息一下下,你還記得我們的這個BinderProxy返回到什么地方嗎?哈哈,反正我是記得;因為我都記下來了,哈哈;BinderProxyBinderInternal.getContextObject()返回的,即這個BinderProxy將作為ServiceManagerNative.java 中static public IServiceManager asInterface(IBinder obj)方法的參數IBinder obj;如果Binder通信確實跨進程ServiceManagerNative.java的asInterface方法將返回
new ServiceManagerProxy(BinderProxy binderProxy)

基于android的app開發。

到這里我想使用goto 語句了,調到我想去的地方,還記得我們是從什么時候開始分析這個IBinder對象的嗎?

------> ContextImpl.java
? ? ? ?registerService(POWER_SERVICE, new ServiceFetcher()
{
? ? ? ? ? ? ? ?public Object createService(ContextImpl ctx) {
? ? ? ? ? ? ? ? ? ?IBinder b = ServiceManager.getService(POWER_SERVICE);
? ? ? ? ? ? ? ? ? ?IPowerManager service = IPowerManager.Stub.asInterface(b);
? ? ? ? ? ? ? ? ? ?//調用IPowerManger.stub.asInterface,傳入的IBinder對象參數是從
? ? ? ? ? ? ? ? ? ?//ServiceManager.getService(POWER_SERVICE)獲取的
? ? ? ? ? ? ? ? ? ?if (service == null) {
? ? ? ? ? ? ? ? ? ? ? ?Log.wtf(TAG, "Failed to get power manager service.");
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ?return new PowerManager(ctx.getOuterContext(),
? ? ? ? ? ? ? ? ? ? ? ? ? ?service, ctx.mMainThread.getHandler())
;//返回PowerManager對象,
? ? ? ? ? ? ? ? ? ?//這里的service就是PowerManger類中的mService,
//我們在應用層調用的 ?(PowerManager) getSystemService(Context.POWER_SERVICE)
//得到的powerManger對象就是這里返回的new PowerManager,這部分代碼跟著邏輯就能看到;
? ? ? ? ? ? }});

我們重新回到ContextImpl.java 中開始分析, IBinder b = ServiceManager.getService(POWER_SERVICE);其實就是ServiceManagerProxy的getService方法,ServiceManagerProxy類中mRemote的值就是BinderProxy,所以 IBinder b = ServiceManager.getService(POWER_SERVICE)最終會調用ServiceManagerProxy的方法;

------> ServiceMangerNative.java ——>ServiceManagerProxy
? ?public IBinder getService(String name) throws RemoteException
{
? ? ? ?Parcel data = Parcel.obtain();
? ? ? ?Parcel reply = Parcel.obtain();
? ? ? ?data.writeInterfaceToken(IServiceManager.descriptor);
? ? ? ?data.writeString(name);
? ? ? ?mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
? ? ? ?IBinder binder = reply.readStrongBinder();//這里返回IBinder對象
? ? ? ?reply.recycle();
? ? ? ?data.recycle();
? ? ? ?return binder;
? ?}

IPowerManager service = IPowerManager.Stub.asInterface(b),這里asInterface方法的參數b就是ServiceManagerProxy類中getService返回的IBinder,這里是通過reply.readStrongBinder();reply是一個Parcel;

/frameworks/base/core/java/android/os/Parcel.java

安卓設置app,

------> Parcel.javapublic final IBinder readStrongBinder() {return nativeReadStrongBinder(mNativePtr);//JNI方法}

我們根據Android JNI命名規則,可以到android_os_Parcel.cpp中查看nativeReadStrongBinder方法:

------> android_os_Parcel.cpp
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
? ?Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
? ?if (parcel != NULL) {
? ? ? ?return javaObjectForIBinder(env, parcel->readStrongBinder());//這個方法前面有說過,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//根據parcel->readStrongBinder()的值返回,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//提前透露一下,parcel->readStrongBinder()返回的值是BpBinder對象
? ?}
? ?return NULL;
}

parcel->readStrongBinder()

------> Parcel.cpp
sp<IBinder> Parcel::readStrongBinder() const
{
? ?sp<IBinder> val;
? ?unflatten_binder(ProcessState::self(), *this, &val);//核心,解析Binder
? ?return val;
}
------> Parcel.cpp
status_t unflatten_binder(const sp<ProcessState>& proc,
? ?const Parcel& in, sp<IBinder>* out)

{
? ?const flat_binder_object* flat = in.readObject(false);

? ?if (flat) {
? ? ? ?switch (flat->type) {
? ? ? ? ? ?case BINDER_TYPE_BINDER://Binder實體
? ? ? ? ? ? ? ?*out = reinterpret_cast<IBinder*>(flat->cookie);
? ? ? ? ? ? ? ?return finish_unflatten_binder(NULL, *flat, in);
? ? ? ? ? ?case BINDER_TYPE_HANDLE://Binder 引用,我們這里是通過ServiceManager.getService獲取的服務代理,即Binder引用
? ? ? ? ? ? ? ?*out = proc->getStrongProxyForHandle(flat->handle);//核心核心,是不是很熟悉呢???
? ? ? ? ? ? ? ?//該方法返回一個new BpBinder(flat->handle),這里的new BpBinder將會傳遞給readStringBinder方法的&val然后直接返回;
? ? ? ? ? ? ? ?return finish_unflatten_binder(
? ? ? ? ? ? ? ? ? ?static_cast<BpBinder*>(out->get()
), *flat, in)
;//類型轉換
? ? ? ?}
? ?}
? ?return BAD_TYPE;
}

Parcel.cpp中的readStrongBinder方法將返回一個new BpBinder()對象,接著繼續返回給android_os_Parcel.cpp的android_os_Parcel_readStrongBinder,在android_os_Parcel_readStrongBinder中調用javaObjectForIBinder方法將這個BpBinder對象轉換為Java 層的BinderProxy對象返回,javaObjectForIBinder還會調用SetLongField將獲取到的BpBinder對象保存到java層BinderProxy類的mObject變量中,所以呢所以呢???ServiceManagerProxy的getService方法將返回一個BinderProxy對象



再回到ContextImpl中,你將會明白所有參數:
IBinder b = ServiceManager.getService(POWER_SERVICE) ? ?//IBinder b其實就是一個BinderProxy對象,是不是和前面透露的保持一致,其實我都怕透露出錯,哈哈
IPowerManager service = IPowerManager.Stub.asInterface(b);//這里我們知道asInterface(b)最終會將參數b傳遞到IPowerManager.Stub.Proxy的構造函數,將BinderProxy對象賦值給IPowerManager.Stub.Proxy的mRemoteIPowerManager.Stub.asInterface(b)調用最終會返回IPowerManager.Stub.Proxy對象


有沒有真相大白的感覺,困擾你的mRemote終于驗明正身了;又沒有很興奮激動,反正我還是比較激動的。


小結:本小結主要闡述了Binder通信從APP層到framework層的通信過程,即
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE)
boolean bool = powerManager.isScreenOn()=========>mService.isInteractive(mService是IPowerManager對象)=========>mRemote.transact(Stub.TRANSACTION_isInteractive, _data, _reply, 0)(mRemote是一個BinderProxy對象)=========>BinderProxy.transact;下一篇文章將從BinderProxy開始分析




與之相關

1?三步掌握 Android 中的 AIDL



微信號:code-xiaosheng





公眾號

「code小生」



版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/183459.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息