Android的zygote SystemServer的启动,android音视频开发pdf

startSystemServer ? “start-system-server” : “”);

} else if (className) {

// Remainder of args get passed to startup class main()

runtime.mClassName = className;

runtime.start(“com.android.internal.os.RuntimeInit”,

application ? “application” : “tool”);

} else {

}

复制代码

可以看到,app_process 里面定义了三种应用程序类型:

  1. Zygote:  com.android.internal.os.ZygoteInit

  2. System Server, 不单独启动,而是由Zygote启动

  3. 其他指定类名的Java 程序,比如说常用的 am. /system/bin/am 其实是一个shell程序,它的真正实现是

exec app_process b a s e / b i n c o m . a n d r o i d . c o m m a n d s . a m . A m " base/bin com.android.commands.am.Am " base/bincom.android.commands.am.Am"@"

这些Java的应用都是通过 AppRuntime.start(className)开始的。从第一张大图可以看出,其实AppRuntime是AndroidRuntime的子类,它主要实现了几个回调函数,而start()方法是实现在AndroidRuntime这个方法类里。什么是AnroidRuntime? 我们接下来马上开始。

需要注意的是Zygote并不是Init启动的第一个程序,从PID可以看出来,在它之前,一下Native实现的重要System Daemon (后台进程)可能先起来,比如 ServiceManager (service的DNS服务).

2. AndroidRuntime

==================

首先,什么是Runtime ?看看Wiki给的几种解释:

我倾向这里指的是后者,看看更进一步的解释:

In computer programming, a runtime library is the API used by a compiler to invoke some of the behaviors of a runtime system. The runtime system implements the execution model and other fundamental behaviors of a programming language. The compiler inserts calls to the runtime library into the executable binary. During execution (run time")) of that computer program, execution of those calls to the runtime library cause communication between the application and theruntime system. This often includes functions for input and output, or for memory management.

归纳起来的意思就是,Runtime 是支撑程序运行的基础库,它是与语言绑定在一起的。比如:

  • C Runtime:就是C standard lib, 也就是我们常说的libc。(有意思的是, Wiki会自动将“C runtime" 重定向到 “C Standard Library”).

  • Java Runtime: 同样,Wiki将其重定向到” Java Virtual Machine", 这里当然包括Java 的支撑类库(.jar).

  • AndroidRuntime:  显而易见,就是为Android应用运行所需的运行时环境。这个环境包括以下东东:

  • Dalvik VM: Android的Java VM, 解释运行Dex格式Java程序。每个进程运行一个虚拟机(什么叫运行虚拟机?说白了,就是一些C代码,不停的去解释Dex格式的二进制码(Bytecode),把它们转成机器码(Machine code),然后执行,当然,现在大多数的Java 虚拟机都支持JIT,也就是说,bytecode可能在运行前就已经被转换成机器码,从而大大提高了性能。过去一个普遍的认识是Java 程序比C,C++等静态编译的语言慢,但随着JIT的介入和发展,这个已经完全是过去时了,JIT的动态性运行允许虚拟机根据运行时环境,优化机器码的生成,在某些情况下,Java甚至可以比C/C++跑得更快,同时又兼具平台无关的特性,这也是为什么Java如今如此流行的原因之一吧)。

  • Android的Java 类库, 大部分来自于 Apache Hamony, 开源的Java API 实现,如 java.lang, java.util, java.net. 但去除了AWT, Swing 等部件。

  • JNI: C和Java互调的接口。

  • Libc: Android也有很多C代码,自然少不了libc,注意的是,Android的libc叫 bionic C.

OK, 那就首先看看AndroidRuntime是怎么搭建起来的吧

上图给出了Zygote启动的大概流程,入口是AndroidRuntime.start(), 根据传入参数的不同可以有两种启动方式,一个是 “com.android.internal.os.RuntimeInit”, 另一个是 ”com.android.internal.os.ZygoteInit", 对应RuntimeInit 和 ZygoteInit 两个类, 图中用绿色和粉红色分别表示。这两个类的主要区别在于Java端,可以明显看出,ZygoteInit 相比 RuntimeInit 多做了很多事情,比如说 “preload", “gc” 等等。但是在Native端,他们都做了相同的事, startVM() 和 startReg(), 让我们先从这里开始吧。

从类图中看出,JavaVM 和 JNIEnv 是连结 AndroidRuntim 和 Dalvik VM 之间的唯一两个关卡,它隐藏了Dalvik 里面的实现细节,事实上,他就是两个函数指针结构体,给本地代码提供访问Java资源的接口。JNIEnv则相对于线程,通过JNIEnv的指针最终可以对应到Dalvik VM 内部的Thread 结构体,所有的调用就在这个结构体上下文完成。而JavaVM 对应的是DVMGlobal, 一个进程唯一的结构体,他内部维护了一个线程队列threadList,存放每个Thread 结构体对象, 同时还有各类状态的对象列表,及存放GC的结构体,等等。本文无法深入,只作简单介绍。

  • JavaVM 和 JNIENV

  • 复制代码

struct _JavaVM {

const struct JNIInvokeInterface* functions; //C的函数指针

#if defined(__cplusplus) …

jint GetEnv(void** env, jint version)

{ return functions->GetEnv(this, env, version); }

#endif /*__cplusplus*/

};

struct JNIInvokeInterface {

void* reserved0;

jint (*DestroyJavaVM)(JavaVM*);

jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);

jint (*DetachCurrentThread)(JavaVM*);

jint (*GetEnv)(JavaVM*, void**, jint);

jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);

};

复制代码

里面最常见的接口就是GetEnv(), 它返回一个JNIEnv对象,对应于每个DVM线程。JNIEnv的定义很长,有兴趣的同学可以到Jni.h 里面找,这里我们只看看这个对象是如何获static jint GetEnv(JavaVM* vm, void** env, jint version) {

  • 复制代码

Thread* self = dvmThreadSelf(); //获取当前线程对象。

if (version < JNI_VERSION_1_1 || version > JNI_VERSION_1_6) {

return JNI_EVERSION;

} //检查版本号,Android 4.3对应 1.6

… *env = (void*) dvmGetThreadJNIEnv(self); //很简单,见最下面一行

dvmChangeStatus(self, THREAD_NATIVE);

return (*env != NULL) ? JNI_OK : JNI_EDETACHED;

}

INLINE JNIEnv* dvmGetThreadJNIEnv(Thread* self) { return self->jniEnv; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值