Android启动流程浅谈

Posted ShouCeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android启动流程浅谈相关的知识,希望对你有一定的参考价值。

一、开机启动流程:

android系统启动是由BootLoader引导开机,然后依次进入kernel、Native、Framework、App。

二、冷起进程创建流程:

进程的创建,主要涉及到两个进程的通信
system_server进程和Zygote进程:

  • system_server进程:是用于管理整个Java framework层,包含ActivityManager,PowerManager等各种系统服务;
  • Zygote进程:是Android系统的首个Java进程,Zygote是所有Java进程的父进程,包括 system_server进程以及所有的App进程都是Zygote的子进程,注意这里说的是子进程。

1、AMS发送请求启动进程

//文件位置:/Users/XXX/Library/Android/sdk/sources/android-30/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
final ProcessRecord startProcessLocked(。。。) 
    return mProcessList.startProcessLocked(。。。);


//文件位置:/Users/duanshoucheng/Library/Android/sdk/sources/android-30/com/android/server/am/ProcessList.java
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
        int mountExternal, String seInfo, String requiredAbi, String instructionSet,
        String invokeWith, long startTime) 
    try 
        final Process.ProcessStartResult startResult;
        if (hostingRecord.usesWebviewZygote()) 
            startResult = startWebView(。。。); //Process.startWebView,是静态方法
         else 
            startResult = Process.start(。。。);
        
        checkSlow(startTime, "startProcess: returned from zygote!");
        return startResult;
     finally 
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    


//文件位置:/Users/duanshoucheng/Library/Android/sdk/sources/android-30/android/os/Process.java
Process.start(...) ->ZYGOTE_PROCESS.start(...) -> ... -> zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),...);  //会有两次机会和Zygote进程match。这里是LocalSocket

HostRecord构造参数HostingType,可取值:“activity”,“service”, “broadcast”, “contentProvider”
Java层进程的创建都是通过Process.start()方法,告知Zygote进程创建fork子进程,创建新进程后将ActivityThread类加载到新进程,并调用ActivityThread.main()方法。

2、Zygote处理请求

zygote进程在系统开机时就创建了。

//文件位置:/Users/xxx/Library/Android/sdk/sources/android-30/com/android/internal/os/ZygoteInit.java
@UnsupportedAppUsage
public static void main(String[] argv) 
        ZygoteServer zygoteServer = null;
         ...
        try 
            ...
            // 跟进该方法内,可以看到都是提前加载框架通用类和系统资源等
            if(!enableLazypreload)
                preload(bootTimingsTraceLog);
            
            ...
            // 创建zygote进程的socket server服务端对象
            zygoteServer = new ZygoteServer(isPrimaryZygote);
            
            if (startSystemServer) 
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
                if (r != null) 
                    r.run();
                    return;
                
            
            ...
            // 等待AMS发请求过来
            caller = zygoteServer.runSelectLoop(abiList);
            ...
        
        ...
    
    
    //文件位置:/Users/xxx/Library/Android/sdk/sources/android-30/com/android/internal/os/ZygoteServer.java
 ZygoteServer.runSelectLoop(...) ->
 ZygoteConnection.processCommand -> handleChildProc(...);
 private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) 
       ...
        if (parsedArgs.mInvokeWith != null) 
           ...
         else 
            if (!isZygote) 
                // 继续进入ZygoteInit#zygoteInit继续完成子应用进程的相关初始化工作
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            
        
    

3、应用进程初始化

public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) 
   
    RuntimeInit.redirectLogStreams();

    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit(); //native方法,jni调用启动进程的binder线程池
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
            classLoader);

应用进程至此就启动了,启动之后需要main方法的入口:

//文件位置:/Users/xxx/Library/Android/sdk/sources/android-30/com/android/internal/os/RuntimeInit.java

protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) 
    ...
    final Arguments args = new Arguments(argv);
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);


protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) 
    Class<?> cl;

    try 
        //反射加载创建ActivityThread类对象
        cl = Class.forName(className, true, classLoader);
     catch (ClassNotFoundException ex) 
        throw new RuntimeException(
                "Missing class when invoking static main " + className, ex);
    

    Method m;
    try 
        //反射调用main方法
        m = cl.getMethod("main", new Class[]  String[].class );
     catch (NoSuchMethodException ex) 
        throw new RuntimeException(
                "Missing static main on " + className, ex);
     catch (SecurityException ex) 
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) 
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    
    /*
     * This throw gets caught in ZygoteInit.main(), which responds
     * by invoking the exception's run() method. This arrangement
     * clears up all the stack frames that were required in setting
     * up the process.
     */
    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 );
         ...
    

4、新进程app

//文件位置:/Users/xxx/Library/Android/sdk/sources/android-30/android/app/ActivityThread.java
public static void main(String[] args) 
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);

    if (sMainThreadHandler == null) 
        sMainThreadHandler = thread.getHandler();
    
    Looper.loop();


@UnsupportedAppUsage
final ApplicationThread mAppThread = new ApplicationThread(); //内部类,继承IApplicationThread.Stub

@UnsupportedAppUsage
private void attach(boolean system, long startSeq) 
    
    RuntimeInit.setApplicationObject(mAppThread.asBinder());
    final IActivityManager mgr = ActivityManager.getService();
    mgr.attachApplication(mAppThread, startSeq);

简单总结下:
初始化完,主线程就有了完整的 Looper、MessageQueue、Handler,此时 ActivityThread 的 Handler 就可以开始处理 Message,包括 Application、Activity、ContentProvider、Service、Broadcast 等组件的生命周期函数,都会以 Message 的形式,在主线程按照顺序处理。

5、总结

应用进程的启动是被动式的,在桌面点击图标启动一个组件如Activity实,如果该进程不存在,就会创建并启动进程。应用进程是由Zygote进程fork创建的,AMS在需要创建应用进程时,会通过socket并通知到Zygote进程进程在开机阶段就创建好的socket服务端,然后由Zygote进程fork创建出应用进程。

三、Service启动流程

1、startService调用链

启动方式:startService()和binderService()。也是由ActivityManagerService来完成。
Launcher#startService()–> ContextWrapper#startService()–>ContextImpl#startService() -->

//文件位置:/Users/xxx/Library/Android/sdk/sources/android-30/android/app/ContextImpl.java
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
        UserHandle user) 
    try 
        validateServiceIntent(service);
        service.prepareToLeaveProcess(this); //ActivityManagerService
        ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                getOpPackageName(), getAttributionTag(), user.getIdentifier());
        ...
        return cn;
     catch (RemoteException e) 
        throw e.rethrowFromSystemServer();
    

获取AMS:

//文件位置:/Users/xxx/Library/Android/sdk/sources/android-30/android/app/ActivityManager.java
@UnsupportedAppUsage
public static IActivityManager getService() 
    return IActivityManagerSingleton.get(); //其实就是ActivityManagerService,AMS也是继承该类


private static IActivityTaskManager getTaskService() 
    return ActivityTaskManager.getService();


@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() 
            @Override
            protected IActivityManager create() 
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            
        ;
// AMS
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, boolean requireForeground, String callingPackage,
        String callingFeatureId, int userId)
        throws TransactionTooLargeException 
           ...
        ComponentName res;
        try 
            res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid,
                    requireForeground, callingPackage, callingFeatureId, userId);
         finally 
            Binder.restoreCallingIdentity(origId);
        
        return res;
    

参数:

  • caller:类型是IApplicationThread,是ActivityThread.java内部类,IApplicationThread.Stub的子类
  • service:Intent类型,包含需要运行的service信息
  • callingPackage: String类型,调用该方法的package
    然后ActiveService#startServiceLocked -> ActiveService#startServiceInnerLocked->ActiveService#bringUpServiceLocked
//文件位置: /Users/xxx/Library/Android/sdk/sources/android-30/com/android/server/am/ActiveService.java

//2848行,bindService最后也会走这里
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
        boolean whileRestarting, boolean permissionsReviewRequired)
        throws TransactionTooLargeException 
    if (r.app != null && r.app.thread != null) 
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    
    ....
        if (app != null && app.thread != null) 
            try 
                app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                realStartServiceLocked(r, app, execInFg); //启动服务
                return null;
            ...
            

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        
    

    // 进程没启动,需要启动进程
    if (app == null && !permissionsReviewRequired) 
        if ((app=mAm.startProcessLocked(...) 
            ...
        
    
...
    return null;

总结下:该方法流程比较多,重要的是realStartServiceLocked和startProcessLocked两个启动方法,如果进程不存在,执行AMS#startProcessLocked–>AMS#attachApplicationLocked,然后执行realStartServiceLocked.

2、startProcessLocked创建进程

AMS#startProcessLocked -> ProcessList#startProcessLocked,之后的流程参考第二节,下面是第二节之后继续执行的流程:

//AMS.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) 
    if (thread == null) 
        throw new SecurityException("Invalid application interface");
    
    synchronized (this) 
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    


private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) 
        ...
        
        thread.bindApplication(processName, appInfo, providerList,
        instr2.mClass,
        profilerInfo, instr2.mArguments,
        instr2.mWatcher,
        instr2.mUiAutomationConnection, testMode,
        mBinderTransactionTrackingEnabled, enableTrackAllocation,
        isRestrictedBackupMode || !normalMode, app.isPersistent(),
        new Configuration(app.getWindowProcessController().getConfiguration()),
        app.compat, getCommonServicesLocked(app.isolated),
        mCoreSettingsObserver.getCoreSettingsLocked(),
        buildSerial, autofillOptions, contentCaptureOptions,
        app.mDisabledCompatChanges);
        ...
        
// Find any services that should be running in this process...
        if (!badApp) 
            try 
                didSomething |= mServices.attachApplicationLocked(app, processName);
            //mServices是ActiveService    

继续

boolean attachApplicationLocked(ProcessRecord proc, String processName)
        throws RemoteException 
    boolean didSomething = false;
    // Collect any services that are waiting for this process to come up.
    if (mPendingServices.size() > 0) 
                ...
                realStartServiceLocked(sr, proc, sr.createdFromFg);
                didSomething = true;
                ...
    
    return didSomething;

看到了吧,第6行,创建了新的进程之后,会继续执行ActiveService#realStartServiceLocked。
忽略第2小节,继续第1小节的流程:realStartServiceLocked().

3、realStartServiceLocked继续启动服务

//文件位置: /Users/xxx/Library/Android/sdk/sources/android-30/com/android/server/am/ActiveService.java
private final void realStartServiceLoc

以上是关于Android启动流程浅谈的主要内容,如果未能解决你的问题,请参考以下文章

Android启动流程浅谈

浅谈Tomcat的启动流程(源码级别)

浅谈HDFS源码的启动与心跳流程

[转] 浅谈Linux系统的启动流程

Android Camera getCameraIdList流程 (android P)

浅谈tomcat1.7 --- windows环境tomcat启动的流程;