美文网首页
android app启动流程解析

android app启动流程解析

作者: jackzhoud | 来源:发表于2017-04-27 09:46 被阅读0次

    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

    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的起始入口。

         进程创建

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

    ActivityThread启动细节

    这里写图片描述

    两个重要内部类

    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<ProviderInfo> 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<String, IBinder> 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<ProviderInfo> 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启动总流程.jpg

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

    相关文章

      网友评论

          本文标题:android app启动流程解析

          本文链接:https://www.haomeiwen.com/subject/hodgzttx.html