美文网首页
Android 启动过程源码 逐行讲解 笔记

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

作者: KennGM | 来源:发表于2021-10-12 18:23 被阅读0次

    安卓开发那么多年还是第一次看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("<pre-initialized>");
            //通过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("<pre-initialized>", 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 启动过程源码 逐行讲解 笔记

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