Android 启动过程源码 逐行讲解 笔记

安卓开发那么多年还是第一次看Android 的main方法

他在ActivityThread这个类里面

 public static void main(String[] args) {
        //开启追踪 说白了就是写Systrace日志,然后给性能调试使用,调用的是native方法
        //使用system/core/include/cutils/trace.h. 和 frameworks/native/cmds/atrace/atrace.cpp.
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        //hook 系统的 CloseGuard 类,该类是用于监测某些类是否正常关闭的,比如 cursor,现在把这个检测先关闭
        CloseGuard.setEnabled(false);

        //初始化环境变量实际上就是得到一个当前进程的用户id 
        //实际通过system/core/libcutils/multiuser.c 获取
        Environment.initForCurrentUser();

        // 往核心库里面写日志
        EventLogger.setReporter(new EventLoggingReporter());

        //读取ca证书的位置路径是/data/misc/user/($userId) 然后data是通过环境变量获取的,此外Environment.getUserConfigDirectory这是个过时的方法
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        //设置进程名
        Process.setArgV0("");
        //通过ThreadLocal创建一个Looper ,一个线程只能有一个,主线程在这里创建, 主线程的是false即不能通过quit方法退出
        Looper.prepareMainLooper();

        // 序列号的标识符。 与此进程启动相关联。 它将在进程开始时作为参数之一提供。
        // 参数格式"seq=114" ,即startSeq最后可能等于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);

        //初始化主线程的Handler
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

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

        // 完成初始化发送事件结束
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        //主线程进入循环状态
        Looper.loop();
        //主线程循环意外退出
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

thread.attach(false, startSeq);

   private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {//主线程
            //设置首次绘制页面时 开启JIT实时编译
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            //给Track发送应用名称APNM给DDMS使用
            android.ddm.DdmHandleAppName.setAppName("", UserHandle.myUserId());
            //把ApplicationThread中的Binder交给ART 虚拟机,这东西是预编译的
            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 {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } else {
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

        // add dropbox logging to libcore
        DropBox.setReporter(new DropBoxReporter());

        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
            synchronized (mResourcesManager) {
                // We need to apply this change to the resources immediately, because upon returning
                // the view hierarchy will be informed about it.
                if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
                        null /* compat */)) {
                    updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                            mResourcesManager.getConfiguration().getLocales());

                    // This actually changed the resources! Tell everyone about it.
                    if (mPendingConfiguration == null
                            || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
                        mPendingConfiguration = globalConfig;
                        sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                    }
                }
            }
        };
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

你可能感兴趣的:(Android 启动过程源码 逐行讲解 笔记)