cq9电子游戏送彩金可提现,澳门游戏在线平台,所有澳门电子游   产品展示   荣誉资质   常见问题   工程案例
当前位置:cq9电子游戏送彩金可提现,澳门游戏在线平台,所有澳门电子游 > 工程案例 > 详情
工程案例列表

大厂喜欢考的 Binder 体系服务注册题目怎么破?

时间:2020-02-04 13:20来源:http://www.336te.cn 作者:cq9电子游戏送彩金可提现,澳门游戏在线平台,所有澳门电子游 点击:

原标题:大厂喜欢考的 Binder 体系服务注册题目怎么破?

作者 | 刘看舒

本文经授权转载自后厂技术官(ID:houchangcto)

责编 | 胡巍巍

在shu.cn/framework/binder/3-addservice.html 这篇文章中,吾介绍的是Native Binder中的体系服务的注册过程。

这一过程的中央是ServiceManager,而在Java Binder中,也有一个ServiceManager,只不过这个ServiceManager是Java文件。

既然要将体系服务注册到ServiceManager,那么必要选择一个体系服务为例,这边以常见的AMS为例。

将AMS注册到ServiceManager

在AMS的setSystemProcess手段中,会调用ServiceManager的addService手段,如下所示。

睁开全文

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void setSystemProcess() {

try {

ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,

DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);//1

....

} catch (PackageManager.NameNotFoundException e) {

throw new RuntimeException(

"Unable to find android system package", e);

}

...

}

注解1处的Context.ACTIVITY_SERVICE的值为"activity",作用就是将AMS注册到ServiceManager中。接着来看ServiceManager的addService手段。

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

public static void addService(String name, IBinder service, boolean allowIsolated,

int dumpPriority) {

try {

getIServiceManager().addService(name, service, allowIsolated, dumpPriority);

} catch (RemoteException e) {

Log.e(TAG, "error in addService", e);

}

}

主要分析getIServiceManager手段返回的是什么,代码如下所示。

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

private static IServiceManager getIServiceManager() {

if (sServiceManager != null) {

return sServiceManager;

}

sServiceManager = ServiceManagerNative

.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));

return sServiceManager;

}

讲到这边,已经积累了几个点必要分析,别离是:

BinderInternal.getContextObject() ServiceManagerNative.asInterface() getIServiceManager().addService()

现在吾们来各个击破它们。

1.1 BinderInternal.getContextObject()

Binder.allowBlocking的作用是将BinderProxy的sWarnOnBlocking值置为false。

主要来分析BinderInternal.getContextObject()做了什么,这个手段是一个Native手段,找到它对答的函数:

frameworks/base/core/jni/android_util_Binder.cpp

static const JNINativeMethod gBinderInternalMethods[] = {

{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },

...

};

对答的函数为android_os_BinderInternal_getContextObject:

frameworks/base/core/jni/android_util_Binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)

{

sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//1

return javaObjectForIBinder(env, b);

}

ProcessState::self()的作用,是创建ProcessState,注解1处最后返回的是BpBinder。

BpBinder是Native Binder中的Client端,这表明Java层的ServiceManager必要Native层的BpBinder。

但是这个BpBinder在Java层是无法直接行使,那么就必要传入javaObjectForIBinder函数来做处理。

其内部会创建一个BinderProxy对象,如许吾们得知 BinderInternal.getContextObject()最后得到的是BinderProxy。

BinderProxy是Java Binder的客户端的代外。

必要仔细的一点是,这个传入的BpBinder会保存到BinderProxy的成员变量mObject中,后续会再次挑到这个点。

1.2 ServiceManagerNative.asInterface()

说到asInterface手段,在Native Binder中也有一个asInterface函数,它的作用是用BpBinder做为参数创建BpServiceManager。

那么在Java Binder中的asInterface手段的作用又是什么?

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

static public IServiceManager asInterface(IBinder obj)

{

if (obj == null) {

return null;

}

IServiceManager in =

(IServiceManager)obj.queryLocalInterface(descriptor);

if (in != null) {

return in;

}

return new ServiceManagerProxy(obj);

}

按照1.1末节,吾们得知obj的值为BinderProxy,那么asInterface手段的作用就是用BinderProxy行为参数创建ServiceManagerProxy。

BinderProxy和BpBinder别离在Jave Binder和Native Binder行为客户端的代外,BpServiceManager议定BpBinder来实现通信、

同样的,ServiceManagerProxy也会将营业的乞求交给BinderProxy来处理。分析到这边,那么:

sServiceManager = ServiceManagerNative

.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));

能够理解为:

sServiceManager = new ServiceManagerProxy(BinderProxy);

}

1.3 getIServiceManager().addService()

按照1.2节的讲解,getIServiceManager()返回的是ServiceManagerProxy。

ServiceManagerProxy是ServiceManagerNative的内部类,它实现了IServiceManager接口。

来查看ServiceManagerProxy的addService手段,

frameworks/base/core/java/android/os/ServiceManagerNative.java::ServiceManagerProxy

public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)

throws RemoteException {

Parcel data = Parcel.obtain();

Parcel reply = Parcel.obtain();

data.writeInterfaceToken(IServiceManager.descriptor);

data.writeString(name);

data.writeStrongBinder(service);//1

data.writeInt(allowIsolated ? 1 : 0);

data.writeInt(dumpPriority);

mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//2

reply.recycle();

data.recycle();

}

注解1处的data.writeStrongBinder很关键,后续会进走分析。这边又看到了Parcel,它是一个数据包装器,将乞求数据写入到Parcel类型的对象data中。

议定注解1处的mRemote.transact发送出往,mRemote实际上是BinderProxy,BinderProxy.transact是native函数,实现的函数如下所示。

frameworks/base/core/jni/android_util_Binder.cpp

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,

jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException

{

if (dataObj == NULL) {

jniThrowNullPointerException(env, NULL);

return JNI_FALSE;

}

Parcel* data = parcelForJavaObject(env, dataObj);//1

if (data == NULL) {

return JNI_FALSE;

}

Parcel* reply = parcelForJavaObject(env, replyObj);//2

if (reply == NULL && replyObj != NULL) {

return JNI_FALSE;

}

IBinder* target = getBPNativeData(env, obj)->mObject.get();//3

if (target == NULL) {

jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");

return JNI_FALSE;

}

...

status_t err = target->transact(code, *data, reply, flags);//4

return JNI_FALSE;

}

注解1和注解2处,将Java层的Parcel对象转化成为Native层的Parcel对象。在1.1末节中,吾们得知BpBinder会保存到BinderProxy的成员变量mObject中,因此在注解3处,从BinderProxy的成员变量mObject中获取BpBinder。

最后会在注解4处调用BpBinder的transact函数,向Binder驱动发送数据,cq9电子游戏送彩金可提现能够看出Java Binder是必要Native Binder声援的,最后的现在标就是向Binder驱动发送和授与数据。

引出JavaBBinder

接着回过头来分析1.3末节遗留下来的data.writeStrongBinder(service),代码如下所示。

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

public final void writeStrongBinder(IBinder ll) {

nativeWriteStrongBinder(mNativePtr, val);

}

nativeWriteStrongBinder是Native手段,实现的函数为android_os_Parcel_writeStrongBinder:frameworks/base/core/jni/android_os_Parcel.cpp

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)

{

Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);

if (parcel != NULL) {

const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));//1

if (err != NO_ERROR) {

signalExceptionForError(env, clazz, err);

}

}

}

接着查看注解1处ibinderForJavaObject函数:frameworks/base/core/jni/android_util_Binder.cpp

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)

{

if (obj == NULL) return NULL;

if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//1

JavaBBinderHolder* jbh = (JavaBBinderHolder*)

env->GetLongField(obj, gBinderOffsets.mObject);

return jbh->get(env, obj);//2

}

if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {

return getBPNativeData(env, obj)->mObject;

}

ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);

return NULL;

}

注解2处,倘若obj是Java层的BinderProxy类,则返回BpBinder。注解1处,倘若obj是Java层的Binder类,那么先获取JavaBBinderHolder对象,然后在注解2处调用JavaBBinderHolder的get函数,代码如下所示。frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder

class JavaBBinderHolder

{

public:

sp<JavaBBinder> get(JNIEnv* env, jobject obj)

{

AutoMutex _l(mLock);

sp<JavaBBinder> b = mBinder.promote();//1

if (b == NULL) {

//obj是一个Java层Binder对象

b = new JavaBBinder(env, obj);//2

mBinder = b;

ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",

b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());

}

return b;

}

sp<JavaBBinder> getExisting()

{

AutoMutex _l(mLock);

return mBinder.promote();

}

private:

Mutex mLock;

wp<JavaBBinder> mBinder;

};

成员变量mBinder是wp<JavaBBinder>类型的弱引用,在注解1处得到sp<JavaBBinder>类型的强引用b,在注解2处创建JavaBBinder并赋值给b。那么,JavaBBinderHolder的get函数返回的是JavaBBinder。

data.writeStrongBinder(service)在本文中等价于:

data.writeStrongBinder(new JavaBBinder(env,Binder))。

讲到这边能够得知ServiceManager.addService()传入的并不是AMS自己,而是JavaBBinder。

解析JavaBBinder

接着来分析JavaBBinder,查看它的组织函数:

frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder

class JavaBBinder : public BBinder

{

public:

JavaBBinder(JNIEnv* env, jobject /* Java Binder */ c)

: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))

{

ALOGV("Creating JavaBBinder %p\n", this);

gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);

gcIfManyNewRefs(env);

}

能够发现JavaBBinder继承了BBinder,那么JavaBBinder的作用是什么呢?

当Binder驱动得到客户端的乞求,紧接着会将反响发送给JavaBBinder,这时会调用JavaBBinder的onTransact函数,代码如下所示:frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder

virtual status_t onTransact(

uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)

{

JNIEnv* env = javavm_to_jnienv(mVM);

ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);

IPCThreadState* thread_state = IPCThreadState::self();

const int32_t strict_policy_before = thread_state->getStrictModePolicy();

jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,

code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);//1

...

return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;

}

在注解1处会调用Java层Binder的execTransact函数:

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

private boolean execTransact(int code, long dataObj, long replyObj,

int flags) {

try {

if (tracingEnabled) {

Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() ":" code);

}

res = onTransact(code, data, reply, flags);//1

} catch (RemoteException|RuntimeException e) {

...

}

...

return res;

}

关键点是注解1处的onTransact函数,AMS实现了onTransact函数,从而完善营业实现。

从这边可有看出,JavaBBinder并异国实现什么营业,当它授与到乞求时,会调用Binder类的execTransact函数,execTransact函数内部又调用了onTransact函数,体系服务会重写onTransact函数来实现自己的营业功能。

Java Binder架构

Binder架构如下图所示。

Native Binder的片面在此前的文章已经讲过,这边主要来说说Java Binder片面,从图中能够看到:

1.Binder是服务端的代外,JavaBBinder继承BBinder,JavaBBinder议定mObject变量指向Binder。

2.BinderProxy是客户端的代外,ServiceManager的addService等手段会交由ServiceManagerProxy处理。

3.ServiceManagerProxy的成员变量mRemote指向BinderProxy对象,以是ServiceManagerProxy的addService等手段会交由BinderProxy来处理。

4.BinderProxy的成员变量mObject指向BpBinder对象,因此BinderProxy能够议定BpBinder和Binder驱动发送数据。

感谢:

《深入理解Android卷二》

《深入理解Android卷三》

http://gityuan.com/2015/11/21/binder-framework/