前言

这个知识点是Android进阶学习必须掌握的知识点之一,也是高阶Android架构师经常问到的点。在这里分想给大家,希望对大家的工作和学习有所帮助。喜欢本文的记得点赞关注哦~

在前面的Android Binder原理(三)系统服务的注册过程这篇文章中,我介绍的是Native Binder中的系统服务的注册过程,这一过程的核心是ServiceManager,而在Java Binder中,也有一个ServiceManager,只不过这个ServiceManager是Java文件。

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

1.将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 b = ProcessState::self()->getContextObject(NULL);//1

return javaObjectForIBinder(env, b);

}

ProcessState::self()的作用是创建ProcessState,注释1处最终返回的是BpBinder,不理解的可以查看Android Binder原理(二)ServiceManager中的Binder机制这篇文章。

BpBinder是Native Binder中的Client端,这说明Java层的ServiceManager需要Native层的BpBinder,但是这个BpBinder在Java层是无法直接使用,那么就需要传入javaObjectForIBinder函数来做处理,其内部会创建一个BinderProxy对象,这样我们得知 BinderInternal.getContextObject()最终得到的是BinderProxy。

在Android Binder原理(六)Java Binder的初始化这篇文章我们讲过,BinderProxy是Java Binder的客户端的代表。

需要注意的一点是,这个传入的BpBinder会保存到BinderProxy的成员变量mObject中,后续会再次提到这个点。

1.2 ServiceManagerNative.asInterface()

说到asInterface方法,在Native Binder中也有一个asInterface函数。在Android Binder原理(二)ServiceManager中的Binder机制这篇文章中讲过IServiceManager的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驱动发送数据,可以看出Java Binder是需要Native Binder支持的,最终的目的就是向Binder驱动发送和接收数据。

2.引出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(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 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 get(JNIEnv* env, jobject obj)

{

AutoMutex _l(mLock);

sp 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 getExisting()

{

AutoMutex _l(mLock);

return mBinder.promote();

}

private:

Mutex mLock;

wp mBinder;

};

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

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

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

讲到这里可以得知ServiceManager.addService()传入的并不是AMS本身,而是JavaBBinder。

3.解析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(&data), reinterpret_cast(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函数来实现自身的业务功能。

4.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最重要最热门的学习方向资料放在了我的GitHub:https://github.com/xieyuliang/Android-P7-(点击蓝色字体可以获取),里面还有不同方向的自学编程路线、面试题集合/面经、及系列技术文章等。

资源持续更新中,欢迎大家一起学习和探讨。

部分资料截图展示:

android java服务,Android进阶学习必会:Java Binder中的系统服务相关推荐

  1. Java毕设项目小组学习系统(java+VUE+Mybatis+Maven+Mysql)

    Java毕设项目小组学习系统(java+VUE+Mybatis+Maven+Mysql) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webst ...

  2. 吹爆系列:教科书级别的Android音视频入门进阶学习手册,学完我成功“挤进”了抖音音视频开发岗

    Android开发工作两年,真的是感觉Android应用层开发没什么前景了,于是打算在网络安全,智能硬件,音视频这几个方向发展,考虑了一段时间,最终决定选择音视频.理由就不说了,既然选择了就要好好深耕 ...

  3. android 壁纸服务,Android开发学习之WallPaper设置壁纸详细介绍与实例

    今天和大家分享的是关于在android中设置壁纸的方法,在android中设置壁纸的方法有三种,分别是: 1.使用wallpapermanager的setresource(int resourceid ...

  4. android+硬件服务,android之硬件访问服务框架

    一.硬件接口描述文件aidl 新增\frameworks\base\core\java\android\os\ILedService.aidl 二.mk编译脚本 修改vi frameworks/bas ...

  5. Android Performance Patterns 系列视频学习记录(持续更新中)

    系列文章旨在记录YouTube上谷歌发布的Android Performance Patterns系列视频,一共79个视频,每个视频也就几分钟.当然对于大部分安卓开发者来说,这些都是基础,可能你会说, ...

  6. android 打印机服务,Android系统打印服务插件printservice开发

    一 简介 从Android4.4开始,系统加入了打印相关的API,可以通过系统打印服务实现打印.对于需要使用打印功能的APP可参考官方教程接入打印服务. 这不是本文的内容,本文介绍打印机厂商如何使自己 ...

  7. Java进阶学习 - Dubbo框架(持续更新中~~)

    Java进阶学习 - Dubbo框架 1.简介 Dobbo是一个高性能的RPC框架,解决了分布式钟的调用问题 优点:解决了分布式系统中互相调用问题 缺点:缺少统一管理的调度中心 2.为什么Dubbo说 ...

  8. android 壁纸服务,Android视频壁纸的实现

    视频壁纸属于动态壁纸,所以视频壁纸就可以用Android系统提供的动态壁纸服务来实现.首先先介绍一下在实现过程中会用到的几个类. WallpaperManager Android提供的用于管理壁纸的类 ...

  9. android 发现服务,Android服务之网络服务发现服务

    自android 4.1 开始实现了一个网络服务的发现服务NsdService,其基于苹果的Bonjour服务发现协议,支持远程服务的发现和零配置. Bonjour协议包括IP地址的自动分配.服务名称 ...

最新文章

  1. SAP MM 盘点单中‘AUn’标记的作用?
  2. 《程序是怎么跑起来的》第六章
  3. 反思找开瓶器的过程:预判选择方法的执行结果 充分主动积极的沟通
  4. [LeetCode] Binary Tree Level Order Traversal 二叉树层次遍历(DFS | BFS)
  5. 和不安全的Android说再见,Google为它添加新铠甲
  6. cassandra可视化工具_一位数据科学家的私房工具清单
  7. 解决FastJson中“$ref 循环引用检测”的问题的几种方式
  8. 杭电2078复习时间
  9. [JAVA网络编程]用Socket与网络调试助手(NetAssist)进行TCP通讯过程中遇到的问题
  10. Ubuntu中EasyPR环境配置
  11. C# 利用Excel及Spire.xls实现用户自定义打印模板
  12. 网络剧网络电影也有“龙标”了,“上线备案号”时代结束
  13. 计算机基础名词(二)
  14. js判断手机,邮箱格式是否正确
  15. 网红汉字手机全屏时钟APP下载
  16. Java RPC 分布式框架性能大比拼,Dubbo排老几?
  17. 在keras中使用gpu加速训练模型;安装cuda;cudnn;cudnn_cnn_infer64_8.dll 不在path中;device_lib.list_local_devices无gpu;挂掉
  18. 神经网络 深度神经网络,主流的神经网络的框架
  19. 服务器端 P44、25-42
  20. 删除内置不卡米教程_“异形钻”也很美,想来点不一样的?

热门文章

  1. STM32 进阶教程 11 - RAM中运行程序
  2. STM32 基础系列教程 28 - USB_DFU
  3. 在Ubuntu上为Android系统编写Linux内核驱动程序
  4. 【PC工具】200416最终百度网盘——最终下载方法及注意事项,代理是什么
  5. 【PC工具】更新免费文库文档下载器,免费下载文库文档
  6. c语言中常用的程序,C语言一些常用语句
  7. C++类class和结构体struct区别
  8. springmvc自定义日期编辑器
  9. Should i Backup all my domain controllers
  10. Lync Server 2013与OWA的集成