从zygote到onCreate应用启动过程分析

在之前的文章讲了app进程大概的启动过程(https://blog.csdn.net/qq_36063677/article/details/125638137),这篇文章细致的分析一下app进程从zygote进程fork出来到onCreate等生命周期方法被执行的过程。

Android应用程序具有两个特点:

  • 进程入口是ActivityThread.main
  • 支持IPC(进程间通信)

从zygote进程的启动过程(https://blog.csdn.net/qq_36063677/article/details/129235187)可以看到,zygote在fork出一个子进程后,handleChildProc()函数开始处理新进程初始化操作,调用ZygoteInit.zygoteInit():

//ZygoteInit.java   
   public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
    
    
        if (RuntimeInit.DEBUG) {
    
    
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
       // 1. 使进程支持IPC(binder进程间通信)
        ZygoteInit.nativeZygoteInit();
       // 2. 调用AcitivtyThraed.main()
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

一、支持IPC

ZygoteInit.nativeZygoteInit()是一个jni实现的native方法,方法实现是调用AndroidRuntime对象的onZygoteInit():

//AndoridRuntime.cpp
static AndroidRuntime* gCurRuntime = NULL;

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    
    
    gCurRuntime->onZygoteInit();
}

AppRuntime继承了AndroidRuntime了,并且实现了onZygoteInit()方法,关于安卓runtime机制后续分析,现在这里挖个坑。

AppRuntime类在熟悉的app_process模块中定义:

// app_main.cpp
class AppRuntime : public AndroidRuntime
{
    
    
    ......
     virtual void onZygoteInit()
    {
    
    
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }
}

又看到了熟悉的ProcessState,binder通信绕不开的对象,关于ProcessState和IPCThreadState,其都被定义在libbinder模块中。

回到ProcessState,startThreadPool调用spawnPooledThread()方法,创建PoolThread线程类,并且启动这个线程。

//ProcessState.cpp
class PoolThread : public Thread {
    
    
public:
    explicit PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    
    }

protected:
    virtual bool threadLoop() 
    {
    
    
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }

    const bool mIsMain;
};

void ProcessState::startThreadPool() {
    
    
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
    
    
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

void ProcessState::spawnPooledThread(bool isMain) {
    
    
    if (mThreadPoolStarted) {
    
    
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

这里的Thread和Java不同,在这里线程run()启动后,调用的是threadLoop()方法,关于threadLoop()是如何被调用的(https://blog.csdn.net/ch853199769/article/details/79917188),ProcessState调用IPCThreadState->joinThreadPool(true)进一步处理。

//IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)
{
    
    
    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());

    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

    status_t result;
    do {
    
    
        processPendingDerefs();
        // now get the next command to be processed, waiting if necessary
        result = getAndExecuteCommand();

        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
    
    
            LOG_ALWAYS_FATAL("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                  mProcess->mDriverFD, result);
        }

        // Let this thread exit the thread pool if it is no longer
        // needed and it is not the main process thread.
        if(result == TIMED_OUT && !isMain) {
    
    
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
        (void*)pthread_self(), getpid(), result);

    mOut.writeInt32(BC_EXIT_LOOPER);
    talkWithDriver(false);
}

可以看到还是通过循环等待消息,getAndExecuteCommand()通过talkWithDriver()访问“/dev/binder”节点,处理其他进程的通信消息,这样安卓应用程序就支持IPC(Binder进程间通信)了。

二、AcitivtyThraed.main()

接下来看RuntimeInit.applicationInit()方法做了什么,其实就是找到参数类中的main方法,返回给一个Runnable执行:

扫描二维码关注公众号,回复: 17272583 查看本文章
//RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
    
    
    .......
        cl = Class.forName(className, true, classLoader);
        m = cl.getMethod("main", new Class[] {
    
     String[].class });
        return new MethodAndArgsCaller(m, argv);
}

    static class MethodAndArgsCaller implements Runnable {
    
    
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
    
    
            mMethod = method;
            mArgs = args;
        }

        public void run() {
    
    
            try {
    
    
                mMethod.invoke(null, new Object[] {
    
     mArgs });
            } catch (IllegalAccessException ex) {
    
    
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
    
    
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
    
    
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
    
    
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }

这个参数就是"android.app.ActivityThread"。

重点分析ActivityThread.main()函数:

// ActivityThread.java
public static void main(String[] args) {
    
    
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

    // Install selective syscall interception
    AndroidOs.install();

    // CloseGuard defaults to true and can be quite spammy.  We
    // disable it here, but selectively enable it later (via
    // StrictMode) on debug builds, but using DropBox, not logs.
    CloseGuard.setEnabled(false);

    Environment.initForCurrentUser();

    // Make sure TrustedCertificateStore looks in the right place for CA certificates
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    // Call per-process mainline module initialization.
    initializeMainlineModules();

    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
    // It will be in the format "seq=114"
    long startSeq = 0;
    if (args != null) {
    
    
        for (int i = args.length - 1; i >= 0; --i) {
    
    
            if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
    
    
                startSeq = Long.parseLong(
                        args[i].substring(PROC_START_SEQ_IDENT.length()));
            }
        }
    }
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);

    if (sMainThreadHandler == null) {
    
    
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
    
    
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

主要操作:

  1. Looper.prepareMainLooper();
  2. ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
  3. Looper.loop();

启动Looper开启消息循环机制,关于Looper可参考(https://blog.csdn.net/qq_36063677/article/details/129369042),这里重点关注操作 2.

因为main()函数是static静态的,先实例化ActivityThread对象,类变量mH在这时被初始化,用于驱动各个事件的Handler,类变量mAppThread也被初始化,它是ActivityThread的内部类ApplicationThread extends IApplicationThread.Stub,是一个binder对象,用于system_server进程和新的App进程通信管理:

    @UnsupportedAppUsage
    final ApplicationThread mAppThread = new ApplicationThread();
    @UnsupportedAppUsage
    final Looper mLooper = Looper.myLooper();
    @UnsupportedAppUsage
    final H mH = new H();

调用thread.attach():

private void attach(boolean system, long startSeq) {
    
    
    //......
    		RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
    
    
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
    
    
                throw ex.rethrowFromSystemServer();
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
    
    
                @Override public void run() {
    
    
                    if (!mSomeActivitiesChanged) {
    
    
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
    
    
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
    
    
                            ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
    
    
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
}

mgr.attachApplication(mAppThread, startSeq);开始和AMS通信,BinderInternal.addGcWatcher()在内存大于3/4的时候告诉ActivityTaskManager释放内存。

attachApplication()后续调用attachApplicationLocked()执行下一步操作:

// ActivityManagerService.java
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    
    
    
    ProcessRecord app;
    app = mPidsSelfLocked.get(pid);
    
    // App死亡回调
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
    
    // 告知App配置信息
                thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);
    
    // 将IApplicationThread关联到ProcessRecord,WindowProcessController
    app.makeActive(thread, mProcessStats);
}

AMS先是通过pid拿到ProcessRecord对象,它保存着正在运行的进程的所有信息,在ProcessList->newProcessRecordLocked()方法中被实例化并返回,ProcessList->handleProcessStartedLocked()方法中调用mService.addPidLocked(app);添加到AMS的mPidsSelfLocked变量中管理。

    @GuardedBy("mService")
    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
            boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
    
    
        //......
        final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
        
        return r;
    }

    @GuardedBy("mService")
    boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
            long expectedStartSeq, boolean procAttached) {
    
    
        //......
        mService.addPidLocked(app);
        
        return true;
    }

成功获取到ProcessRecord对象后,注册app死亡回调,计算初始化一些app相关的配置信息,并通过IApplicationThread接口的bindApplication()通知给app端,关键的是app.makeActive()函数,它告诉system_server进程的ProcessRecord、WindowProcessController对象app进程已经启动了,可以通过IApplicationThread执行下一步操作,如执行Activity的生命周期方法,广播onReceive()等:

// ProcessRecord.java
class ProcessRecord implements WindowProcessListener {
    
    
    
    IApplicationThread thread;  // the actual proc...  may be null only if
                                    // 'persistent' is true (in which case we
                                    // are in the process of launching the app)
    public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
    
    
        //......
            thread = _thread;
            mWindowProcessController.setThread(thread);
    }
}

// WindowProcessController.java
public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
        implements ConfigurationContainerListener {
    
    
    
    // The actual proc...  may be null only if 'persistent' is true (in which case we are in the
    // process of launching the app)
    private IApplicationThread mThread;
}

在makeActive()方法被调用前,ProcessRecord和WindowProcessController对象的IApplicationThread变量都为null,除非是persistent app,在被赋值后,system_server进程有了和app进程沟通的工具,可以回调Activity对象的onCreate(), onResume, onReceive()等:

// ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
    
    
    			//......
    
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken); 		

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                        r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
    
    
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
    
    
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);
}

通过proc.getThread(), r.appToken参数构造ClientTransaction类对象,proc.getThread()就是WindowProcessController的mThread变量,判断当前的生命周期,LaunchActivityItem执行onCreate(),ResumeActivityItem执行onResume(),PauseActivityItem执行onPause(),那么这个事务ClientTransaction是怎么被执行的呢?接着往下看

proc.getThread()被赋值给ClientTransaction的mClient变量,ClientTransaction的执行方法schedule()就是通过mClient实现的:

// ClientTransaction.java

/** Target client. */
private IApplicationThread mClient;

public void schedule() throws RemoteException {
    
    
    mClient.scheduleTransaction(this);
}

mClient就是system_server进程和app进程沟通的桥梁,从此就回到了app进程,回到ActivityThread查看进一步操作:

// ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler {
    
    
    
    private class ApplicationThread extends IApplicationThread.Stub {
    
    
        
		@Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    
    
            ActivityThread.this.scheduleTransaction(transaction);
        }
    }
}

// ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
    
    

    void scheduleTransaction(ClientTransaction transaction) {
    
    
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}

ActivityThread继承了ClientTransactionHandler,scheduleTransaction()方法是通过mH handler发送EXECUTE_TRANSACTION:

class H extends Handler {
    
    
	public void handleMessage(Message msg) {
    
    
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            mTransactionExecutor.execute(transaction);
            if (isSystem()) {
    
    
                // Client transactions inside system process are recycled on the client side
                // instead of ClientLifecycleManager to avoid being cleared before this
                // message is handled.
                transaction.recycle();
            }
            // TODO(lifecycler): Recycle locally scheduled transactions.
            break;
    }
}

在EXECUTE_TRANSACTION消息被接收时处理了ClientTransaction事务,接下去就是执行生命周期方法了。

在IApplicationThread.aidl文件中定义了system_server进程和app进程的通信方法。

猜你喜欢

转载自blog.csdn.net/qq_36063677/article/details/129756237