前言

小菜鸟

手机启动

Android手机在开机Linux内核启动的时候,会加载system/core/init/init.rc文件,启动init进程,这个是Android特有的初始化程序,主要负责

  • 各种复杂工作
  • 负责开关机画面
  • 文件系统的创建和挂载
  • 启动Zygote(孵化器)进程
  • 启动ServiceManager,它是Binder服务管理器,管理所有Android系统服务

fork Zygote

在启动init进程后会fork Zygote进程,它是一个孵化器进程,它的main函数会创建好环境并且等待孵化,接到指令后就会开始fork子进程

  • 创建一个server端的socket, name为zynote,用于和客户端进程通信
  • 预加载类和资源,提高应用启动速度
  • 启动SystemServer进程
  • 监听socket,当有一个应用程序启动时,就会向它发出请求,然后zygote进程fock自己来创建的一个新的子进程。

所以说Android内所有的应用其实都是Zygote的子进程

SystemServer

SystemServer是由zygote进程fork出来的第一个进程,SystemServer和Zygote是Android Framework最重要的2个进程。 系统里面重要的服务都是在这个进程里面开启的,比如ActivityManagerService(AMS)、PackageManagerService(PMS)、WindowManagerService(WMS)。

应用启动流程基本是围绕着ActivityManagerService和ActivityThread展开。

并且负责启动并且管理整个framework。

ActivityManagerService

ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
并且他在SystemServer进程开启的时候,就会直接跟着一起初始化

应用启动

涉及进程

Android开发中,我们可以通过Package包名和Activity类名,来打开一个APP。实际上,项目里的业务代码startActivity()方法并不是直接创建进程、拉起APP的。而是通过一系列的调用,把请求传递给SystemServer的AMS。AMS收到来自客户端的请求后,再通知zygote进程来fork一个新进程,来开启我们的目标APP。APP中所有Activity的生命周期过程,都由AMS(SystemServer进程)统一调度,并在APP自身进程中具体完成。

所以打开应用总共涉及了三个进程:Zygote进程、AMS进程、APP进程

App进程与AMS通过Binder机制进行跨进程通信
AMS(SystemServer进程)与zygote通过Socket进行跨进程通信。

在Android系统中,任何一个Activity的启动都是由AMS和App进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。

启动步骤

1、activity中的startActivity方法最终都会通过拿到ATSM的代理IActivityTaskManager调用的startActivity;

2、之后进入system server进程中的ATMS startActivity,ATMS 经过收集Intent信息,然后使用ActivityStackSupervisor.startSpecificActivityLocked,如果进程已经存在,则直接使用realStartActivityLocked,通过App的binder客户端的代理ApplicationThread调用回到bindApplication,走入Activity的启动流程;如果进程不存在则通过socket链接Zygote,请求fork新的进程;

3、App进程创建完成后,进程启动会调用ActivityThread.main方法,初始化主线程Handler,接着走入attach方法,然后通过AMS的代理调用AMS的attachApplication方法,并将App进程的通信代理ApplicationThread传入AMS;

4、AMS获取到ATMS调用ApplicationThread的bindApplication回到App进程的ActivityThread.ApplicationThread.bindApplication方法中,然后使用Handler切换到主线程执行handleBindApplication,这里初始化了App的进程名字、时间,用户的硬件配置,包括App的文件系统,创建了App的Context实例,Instrumentation实例,调用App的onCreate回调方法,同时告诉AMS APP初始化工作完毕;

5、AMS接着会调用ATMS的attachApplication,最后调用ClientLifecycleManager的scheduleTransaction方法,通过App的Binder代理ApplicationThread回到ActivityThread;

6、进入ActivityThread.ApplicationThread.scheduleTransaction方法之后就进入了Activity的onStart、onResume回调

android系统启动速度 android启动器_java

(图源网络,侵删)

流程

ActivityThread

一个应用,在被点击后首先要fork出一个Zygote进程,接下来执行ActivityThread.main

public static void main(String[] args) { 
    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"); 
}

然后调用ActivityThread的attach方法,然后将activity和AMS通信的Binder代理IApplicationThread实例传入AMS

@UnsupportedAppUsage 
private void attach(boolean system, long startSeq) { 
    sCurrentActivityThread = this; 
    mSystemThread = system; 
    if (!system) { 
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 
                                                UserHandle.myUserId()); 
        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(); 
                    } 
                } 
            } 
        }); 
    }  
}

AMS

接着进入AMS进程,ActivityManagerService.attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread, 
            int pid, int callingUid, long startSeq) { 
            if (app.isolatedEntryPoint != null) { 
                // This is an isolated process which should just call an entry point instead of 
                // being bound to an application. 
                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); 
            } else if (instr2 != null) { 
                thread.bindApplication(processName, appInfo, providers, 
                        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); 
            } else { 
                thread.bindApplication(processName, appInfo, providers, 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); 
            } 
        } catch (Exception e) { 
        } 
        // See if the top visible activity is waiting to run in this process... 
        if (normalMode) { 
            try { 
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); 
            } catch (Exception e) { 
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 
                badApp = true; 
            } 
        } 
        // Find any services that should be running in this process... 
        if (!badApp) { 
            try { 
                didSomething |= mServices.attachApplicationLocked(app, processName); 
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); 
            } catch (Exception e) { 
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 
                badApp = true; 
            } 
        } 
        return true; 
    }
  • thread.bindApplication:该方法主要讲App进程的配置信息通过IApplicationThread Binder通信回传到ActivityThread中;
  • mAtmInternal.attachApplication:mAtmInternal实际就是ActivityTaskManager的实例,通过LocalServices加载;
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);

那么这里相当于走到了ActivityTaskManagerServer的attachApplication中;

bindApplication

@Override 
        public final void bindApplication(String processName, ApplicationInfo appInfo, 
                ProviderInfoList providerList, ComponentName instrumentationName, 
                ProfilerInfo profilerInfo, Bundle instrumentationArgs, 
                IInstrumentationWatcher instrumentationWatcher, 
                IUiAutomationConnection instrumentationUiConnection, int debugMode, 
                boolean enableBinderTracking, boolean trackAllocation, 
                boolean isRestrictedBackupMode, boolean persistent, Configuration config, 
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings, 
                String buildSerial, AutofillOptions autofillOptions, 
                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) { 
            setCoreSettings(coreSettings); 
            AppBindData data = new AppBindData(); 
            data.processName = processName; 
            ..... 
            sendMessage(H.BIND_APPLICATION, data); 
        }

这里的bindApplication主要初始化了AppBindData,然后发送BIND_APPLICATION给APP的主线程BIND_APPLICATION,最后执行了handleBindApplication

case BIND_APPLICATION: 
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); 
                    AppBindData data = (AppBindData)msg.obj; 
                    handleBindApplication(data); 
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
                    break; 
Application的onCreate方法 
private void handleBindApplication(AppBindData data) { 
          mBoundApplication = data; 
        mConfiguration = new Configuration(data.config); 
        mCompatConfiguration = new Configuration(data.config); 
         if (data.initProfilerInfo != null) { 
            mProfiler.profileFile = data.initProfilerInfo.profileFile; 
            mProfiler.profileFd = data.initProfilerInfo.profileFd; 
            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 
            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 
            mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput; 
            if (data.initProfilerInfo.attachAgentDuringBind) { 
                agent = data.initProfilerInfo.agent; 
            } 
        } 
mInstrumentationPackageName = ii.packageName; 
            mInstrumentationAppDir = ii.sourceDir; 
            mInstrumentationSplitAppDirs = ii.splitSourceDirs; 
            mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); 
            mInstrumentedAppDir = data.info.getAppDir(); 
            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 
            mInstrumentedLibDir = data.info.getLibDir(); 
             mInstrumentation.callApplicationOnCreate(app); 
}

这个方法主要在App进程中对App的一些硬件资源配置申请的属性、App的文件夹等完成App基本信息的初始化

并且

mAtmInternal.attachApplication最终会调用mRootActivityContainer.attachApplication(wpc)

RootActivityContainer.attachApplication 
boolean attachApplication(WindowProcessController app) throws RemoteException { 
    final String processName = app.mName; 
    boolean didSomething = false; 
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 
        final ActivityDisplay display = mActivityDisplays.get(displayNdx); 
        final ActivityStack stack = display.getFocusedStack(); 
        if (stack != null) { 
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); 
            //获取前台栈顶第一个非finishing的Activity 
            final ActivityRecord top = stack.topRunningActivityLocked(); 
            final int size = mTmpActivityList.size(); 
            for (int i = 0; i < size; i++) { 
                final ActivityRecord activity = mTmpActivityList.get(i); 
                if (activity.app == null && app.mUid == activity.info.applicationInfo.uid 
                        && processName.equals(activity.processName)) { 
                    try { 
                    //真正启动Activity 
                        if (mStackSupervisor.realStartActivityLocked(activity, app, 
                                top == activity /* andResume */, true /* checkConfig */)) { 
                            didSomething = true; 
                        } 
                    } catch (RemoteException e) { 
                        Slog.w(TAG, "Exception in new application when starting activity " 
                                + top.intent.getComponent().flattenToShortString(), e); 
                        throw e; 
                    } 
                } 
            } 
        } 
    } 
    if (!didSomething) { 
        ensureActivitiesVisible(null, 0, false /* preserve_windows */); 
    } 
    return didSomething; 
}

接着调用ActivityStackSupervisor开始创建Activity

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, 
            boolean andResume, boolean checkConfig) throws RemoteException { 
        try { 
            r.startFreezingScreenLocked(app, 0); 
            //启动tick,收集应用启动慢的信息 
            // schedule launch ticks to collect information about slow apps. 
            r.startLaunchTickingLocked(); 
            r.setProcess(app); 
            try { 
                //创建Activity启动事务 
                // Create activity launch transaction. 
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, 
                        r.appToken); 
                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, app.repProcState, r.icicle, 
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(), 
                        profilerInfo)); 
                //设置目标事务的状态为onResume 
                // Set desired final state. 
                final ActivityLifecycleItem lifecycleItem; 
                if (andResume) { 
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); 
                } else { 
                    lifecycleItem = PauseActivityItem.obtain(); 
                } 
                clientTransaction.setLifecycleStateRequest(lifecycleItem); 
                //通过transaciton方式开始activity生命周期,onCreate,onStart,onResume 
                // Schedule transaction. 
                mService.getLifecycleManager().scheduleTransaction(clientTransaction); 
            } catch (RemoteException e) { 
            } 
        } finally { 
            endDeferResume(); 
        } 
        return true; 
    }

在这个方法中间ClientLifecycleManager.scheduleTransaction最终会调用ClientTransaction的schedule方法,然后这个方法实际上会回调回ActivityThread

运用了IApplicationThread ,也就是AMS和ActivityThread通信的桥梁

APP.onCreate

所以我们调用

@Override 
  public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { 
        ActivityThread.this.scheduleTransaction(transaction); 
  }
  
void scheduleTransaction(ClientTransaction transaction) { 
      transaction.preExecute(this); 
      sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); 
 }

。。。。。。(中间流程没太懂)
最后调用了activity.attach方法。

在这期间,ActivityThread做了这样几件事

  1. 通过反射创建Activity实例,这是通过Instrumentation.newActivity方法实现的;
  2. 调用Activity的onCreate回调;
  3. 通过Activity.attach方法,实例化Window对象;

总结

总结:

  1. 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
    system_server进程接收到请求后,向zygote进程发送创建进程的请求;
  2. Zygote进程fork出新的子进程,即App进程;
  3. App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
  4. system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
  5. App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
  6. 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法