android app启动流程解析

Linux系统启动流程

Linux启动概述

android系统内核实质是使用了Linux的内核,所以在谈到android app启动流程就必须先了解Linux启动流程;当们启动Linux系统时,bootloader会加载linux内核到内存运行,完成后会启动系统的第一个进程(init进程),其完成后会主动创建许多(Daemon)守护进程,保证一些服务能正常开启,如usb daemon进程,保证usb驱动服务正常运行。

android相关概述

init进程会创建android底层的一个Zygote进程,Zygote进程会初始化第一个VM虚拟器,并且加载android相关的framework和app所需要的资源,然后Zygote会开启一个socket来监听外部请求,如果收到请求,会根据已有的VM孵化出一个新的VM和进程;
  随后,Zygote会创建一个System Server进程,此进程会启动android相关的所有核心服务,如AMS(Activity Manager Service)和其他服务进程等,至此,系统会启动第一个App--Home进程,Home进程就是手机的桌面进程。

启动桌面上的app

android app启动流程解析_第1张图片
app_launch

  
  1. 点击桌面app icon -> home的onclick()方法 -> startActivity(Intent)
  
  2. 通过Binder通信进制,将此次启动信息通知给ActivityManagerService,在service内部会做如下操作:
     a. 收集此次启动的对象信息,并封装在intent对象里面去 --- PackageManager的resolveIntent()方法
     b. 验证用户是否有足够的权限来启动这个activity --- grantUriPermissionLocked()
     c. 如果有权限,AMS就会启动这个activity,如果这个activity的进程ProcessRecord为null的话,就会为其创建一个新进程;反之,则回去打开已经存在的activity
     接下来,就开始分析AMS如何具体的启动activity
     
  3. AMS创建进程启动app
    AMS调用startProcessLocked()方法创建新进程,并且通过socket通道传递请求给Zygote进程,Zygote进程会根据收到的请求孵化出一个自身,并调用ZygoteInit.main来实例化一个ActivityThead,ActivityThread的main方法就是作为app的起始入口。

    
android app启动流程解析_第2张图片
进程创建

  4. ActivityThread的main入口是app的起始入口,它是app进程的主线程,管理Activity和Application的启动和生命周期的调用等等

ActivityThread启动细节

android app启动流程解析_第3张图片
这里写图片描述

两个重要内部类

ApplicationThread 和 H

1. main入口

public static void main(String[] args) {
    //创建Looper对象, 创建MessageQueue对象
        Looper.prepareMainLooper();

    //创建自己的ActivityThread对象
        ActivityThread thread = new ActivityThread();
        thread.attach(false);                 // --- 这个很重要

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

        AsyncTask.init();

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

    //进入消息循环
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}
//applicationThread实质是一个binder实例,将binder实例绑定到AMS
private void attach(boolean system) {
    ...
    //获得AMS(ActivityManagerService)实例, AMS的log tag: "ActivityManager"
    IActivityManager mgr = ActivityManagerNative.getDefault();
    //把ApplicationThread对象传给AMS
    mgr.attachApplication(mAppThread);
    ...
}

2. attachApplication绑定ApplicationThread,收集进程的信息,并通过ApplicationThread的bindApplication接口跨进程回传此次新进程信息给ActivityThread

public final class ActivityManagerService extends ActivityManagerNative {
    ...
    public final void attachApplication(IApplicationThread thread) {
        ...
        attachApplicationLocked(thread, callingPid);
        ...
    }
    ...
    private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        ....
        //通过binder,跨进程调用ApplicationThread的bindApplication()方法, 下面代码逻辑重回ActivityThread.java
            thread.bindApplication(processName, appInfo, providers,
                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
                    app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
                    mCoreSettingsObserver.getCoreSettingsLocked());
        ....

    }
}

这个时候还在Binder进程中,利用Handler把消息传回给ActivityThread

//ActivityThread.java

private class ApplicationThread extends Binder implements IApplicationThread{

    ...
        public final void bindApplication(String processName,
                ApplicationInfo appInfo, List providers,
                ComponentName instrumentationName, String profileFile,
                ParcelFileDescriptor profileFd, boolean autoStopProfiler,
                Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
                Configuration config, CompatibilityInfo compatInfo, Map services,
                Bundle coreSettings) {

            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableOpenGlTrace = enableOpenGlTrace;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfileFile = profileFile;
            data.initProfileFd = profileFd;
            data.initAutoStopProfiler = false;
         //发消息
            sendMessage(H.BIND_APPLICATION, data);
        }

    ...
        private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        //通过mH把BIND_APPLICATION消息发给H处理
        mH.sendMessage(msg);
        }
    ...

}

3. ActivityThread的H接收消息并开启逐步执行Application的oncreate

收到BIND_APPLICATION消息后,创建Application对象以及上下文

//ActivityThread.java
public final class ActivityThread {
    ...
    private void handleBindApplication(AppBindData data) {
        ...
        //创建Instrumentation 对象
                java.lang.ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();

        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        //创建app运行时的上下文对象,并对其进行初始化.
        final ContextImpl appContext = new ContextImpl();
        appContext.init(data.info, null, this);
        //这里的data.info是LoadedApk类的对象
        //在这里创建了上层开发者的代码中所涉及的Applicaiton类的对象
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        ...

        //如果有ContentProvider的话, 先加载ContentProvider,后调用Application的onCreate()方法
        List providers = data.providers;
        if (providers != null) {
            installContentProviders(app, providers);
        }
        //调Application的生命周期函数 onCreate()
        mInstrumentation.callApplicationOnCreate(app);

    }
    ...

    private class H extends Handler {
        ...
        public static final int BIND_APPLICATION  = 110;
        ...
        public void handleMessage(Message msg) {
            switch (msg.what) {
                ...
                    case BIND_APPLICATION:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                        AppBindData data = (AppBindData)msg.obj;
                        handleBindApplication(data);//调用ActivityThread的handleBindApplication()方法处理
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                ...
            }
        }
    }
}

执行application的oncreate方法

// LoadedApk.java
public final class LoadedApk {
    ...
    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        Application app = null;
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
        return app;
    }
    ...

}

// Instrumentation.java
public class Instrumentation {
    ...
    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
    ...
}

至此,Application启动流程完了;同理,启动activity的流程大致相同;
activty启动开始点在AMS的attachApplicationLocked方法内部,即bindApplication发送Application后,就会开始准备启动Activity,依次调用mStackSupervisor.attachApplicationLocked(app), 在里面再调用realStartActivityLocked(), 里面再调用app.thread.scheduleLaunchActivity(), 也就是mAppThread的scheduleLaunchActivity(), 在ApplicationThread的scheduleLaunchActivity()内,发送一个"LAUNCH_ACTIVITY"消息, mH处理"LAUNCH_ACTIVITY"时调用handleLaunchActivity(), handleLaunchActivity()分两步, 第一步调performLaunchActivity(),
创建Activity的对象, 依次调用它的onCreate(), onStart(). 第二步调handleResumeActivity(), 调用Activity对象的onResume().

至此, 应用启动的完整流程就分析完整了

手动总结:

android app启动流程解析_第4张图片
Android启动总流程.jpg

参考文章:
http://www.jianshu.com/p/a1f40b39b3de
http://www.jianshu.com/p/a5532ecc8377

你可能感兴趣的:(android app启动流程解析)