return app;
}
}
//调用重载方法
startProcessLocked(…);
}
之所以要判断app.thread,是为了避免当应用进程正在启动的时候,假如又有另一个组件需要启动,导致重复拉起(创建)应用进程。
继续看重载方法startProcessLocked:
//ActivityManagerService.java
private final void startProcessLocked(…){
//应用进程的主线程的类名
if (entryPoint == null) entryPoint = “android.app.ActivityThread”;
ProcessStartResult startResult = Process.start(entryPoint, …);
}
//Process.java
public static final ProcessStartResult start(…){
return zygoteProcess.start(…);
}
来到ZygoteProcess。
//ZygoteProcess.java
public final Process.ProcessStartResult start(…){
return startViaZygote(…);
}
private Process.ProcessStartResult startViaZygote(…){
ArrayList argsForZygote = new ArrayList();
//…处理各种参数
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
其中:
openZygoteSocketIfNeeded打开本地socket
zygoteSendArgsAndGetResult发送请求参数,其中带上了ActivityThread类名
return返回的数据结构ProcessStartResult中会有pid字段
梳理一下:
注意:Zygote进程启动时已经创建好了虚拟机实例,所以由他fork出的应用进程可以直接继承过来用而无需创建。
下面来看Zygote是如何处理socket请求的。
Zygote处理socket请求从 图解Android系统的启动 一文可知,在ZygoteInit的main函数中,会创建服务端socket。
//ZygoteInit.java
public static void main(String argv[]) {
//Server类,封装了socket
ZygoteServer zygoteServer = new ZygoteServer();
//创建服务端socket,名字为socketName即zygote
zygoteServer.registerServerSocket(socketName);
//进入死循环,等待AMS发请求过来
zygoteServer.runSelectLoop(abiList);
}
看到ZygoteServer。
//ZygoteServer.java
void registerServerSocket(String socketName) {
int fileDesc;
//socket真正的名字被加了个前缀,即 “ANDROID_SOCKET_” + “zygote”
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
//创建文件描述符fd
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
//创建LocalServerSocket对象
mServerSocket = new LocalServerSocket(fd);
}
void runSelectLoop(String abiList){
//进入死循环
while (true) {
for (int i = pollFds.length - 1; i >= 0; --i) {
if (i == 0) {
//…
} else {
//得到一个连接对象ZygoteConnection,调用他的runOnce
boolean done = peers.get(i).runonce(this);
}
}
}
}
来到ZygoteConnection的runOnce。
boolean runonce(ZygoteServer zygoteServer){
//读取socket请求的参数列表
String args[] = readArgumentList();
//创建应用进程
int pid = Zygote.forkAndSpecialize(…);
if (pid == 0) {
//如果是应用进程(Zygote fork出来的子进程),处理请求参数
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
}
handleChildProc方法调用了ZygoteInit的zygoteInit方法,里边主要做了3件事:
启动binder线程池(后面分析)
读取请求参数拿到ActivityThread类并执行他的main函数,执行thread.attach告知AMS并回传自己的binder句柄
执行Looper.loop()启动消息循环(代码前面有)
这样应用进程就启动起来了。梳理一下:
下面看下binder线程池是怎么启动的。
启动binder线程池Zygote的跨进程通信没有使用binder,而是socket,所以应用进程的binder机制不是继承而来,而是进程创建后自己启动的。
前边可知,Zygote收到socket请求后会得到一个ZygoteConnection,他的runOnce会调用handleChildProc。
//ZygoteConnection.java
private void handleChildProc(…){
ZygoteInit.zygoteInit(…);
}
//ZygoteInit.java
public static final void zygoteInit(…){
RuntimeInit.commonInit();
//进入native层
ZygoteInit.nativeZygoteInit();
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
来到AndroidRuntime.cpp:
//AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz){
gCurRuntime->onZygoteInit();
}
来到app_main.cpp:
//app_main.cpp
vi
rtual void onZygoteInit() {
//获取单例
sp proc = ProcessState::self();
//在这里启动了binder线程池
proc->startThreadPool();
}
看下ProcessState.cpp:
//ProcessState.cpp
sp ProcessState::self()
{
//单例模式,返回ProcessState对象
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState("/dev/binder");
return gProcess;
}
//ProcessState构造函数
-
ProcessState::ProcessState(const char *driver)
- mDriverName(String8(driver))
, mDriverFD(open_driver(driver)) //打开binder驱动
,//…
{
if (mDriverFD >= 0) {
//mmap是一种内存映射文件的方法,把mDriverFD映射到当前的内存空间
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
}
}
//启动了binder线程池
void ProcessState::startThreadPool()
{
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
//创建线程名字"Binder:KaTeX parse error: Expected group after '_' at position 6: {pid}_̲{自增数字}"
String8 name = makeBinderThreadName();
sp t = new PoolThread(isMain);
//运行binder线程
t->run(name.string());
}
}
ProcessState有两个宏定义值得注意一下:
//ProcessState.cpp
//一次Binder通信最大可以传输的大小是 1MB-4KB*2
#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
//binder驱动的文件描述符fd被限制了最大线程数15
#define DEFAULT_MAX_BINDER_THREADS 15
我们看下binder线程PoolThread长啥样:
class PoolThread : public Thread {
public:
-
explicit PoolThread(bool isMain)
- mIsMain(isMain){}
protected:
virtual bool threadLoop()
{ //把binder线程注册进binder驱动程序的线程池中
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
来到IPCThreadState.cpp:
//IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)
{
r驱动的文件描述符fd被限制了最大线程数15
#define DEFAULT_MAX_BINDER_THREADS 15
我们看下binder线程PoolThread长啥样:
class PoolThread : public Thread {
public:
-
explicit PoolThread(bool isMain)
- mIsMain(isMain){}
protected:
virtual bool threadLoop()
{ //把binder线程注册进binder驱动程序的线程池中
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
来到IPCThreadState.cpp:
//IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)
{
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)