ActivityThread的main()方法简读

来源:互联网 发布:socket编程语言 编辑:程序博客网 时间:2024/05/21 17:25

一、首先,看ActivityThread 的介绍:

 * This manages the execution of the main thread in an * application process, scheduling and executing activities, * broadcasts, and other operations on it as the activity * manager requests.

大概的意思就是说:在应用程序里面管理和执行主线程,调度和执行Activity,广播以及在Activity上的其他业务操作。

二、直接上main()方法。

public static void main(String[] args) {        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");        SamplingProfilerIntegration.start();        // CloseGuard defaults to true and can be quite spammy.  We        // disable it here, but selectively enable it later (via        // StrictMode) on debug builds, but using DropBox, not logs.        CloseGuard.setEnabled(false);        Environment.initForCurrentUser();        // Set the reporter for event logging in libcore        EventLogger.setReporter(new EventLoggingReporter());        // Make sure TrustedCertificateStore looks in the right place for CA certificates        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());        TrustedCertificateStore.setDefaultUserDirectory(configDir);        Process.setArgV0("<pre-initialized>");        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        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");    }

三、一句一句来解读吧。
1、Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
Trace是痕迹,踪迹的意思,是在android.os包下的一个类,主要作用是将跟踪事件写入系统跟踪缓冲区,这些跟踪事件可以用Systrace可视化工具收集和使用。看一下traceBegin()方法,是给代码段写一个跟踪信息。

public static void traceBegin(long traceTag, String methodName) {        if (isTagEnabled(traceTag)) {            nativeTraceBegin(traceTag, methodName);        }    }public static boolean isTagEnabled(long traceTag) {        long tags = sEnabledTags;        if (tags == TRACE_TAG_NOT_READY) {            tags = cacheEnabledTags();        }        return (tags & traceTag) != 0;    }private static native void nativeTraceBegin(long tag, String name);

这里传入了traceTag和methodName,首先就是判断跟踪标签是否启用,如果启用,就调用底层方法,开始跟踪事件。

2、SamplingProfilerIntegration.start();
这个类在com.android.internal.os包下,字面意思翻译就是“抽样分析集成工具”,是集成Dalvik抽样分析器框架。start()是静态方法:

    /**     * Starts the profiler if profiling is enabled.     */    public static void start() {        if (!enabled) {            return;        }        if (samplingProfiler != null) {            Log.e(TAG, "SamplingProfilerIntegration already started at " + new Date(startMillis));            return;        }        ThreadGroup group = Thread.currentThread().getThreadGroup();        SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupThreadSet(group);        samplingProfiler = new SamplingProfiler(samplingProfilerDepth, threadSet);        samplingProfiler.start(samplingProfilerMilliseconds);        startMillis = System.currentTimeMillis();    }

首先拿到当前线程的线程组group ,threadSet ,然后开启抽样分析。

3、CloseGuard.setEnabled(false);
CloseGuard是dalvik.system包下的一个类。CloseGuard 是一种资源清理机制,资源应该被显式关闭清理。setEnabled()明显就是使其失效,不过会在debug builds的时候重现变得有效。

 * CloseGuard is a mechanism for flagging implicit finalizer cleanup of * resources that should have been cleaned up by explicit close * methods (aka "explicit termination methods" in Effective Java).

4、Environment.initForCurrentUser();
Environment大家都很熟悉:环境。

public static void initForCurrentUser() {        final int userId = UserHandle.myUserId();        sCurrentUser = new UserEnvironment(userId);    }

首先拿到当前进程的Id,然后初始化一个UserEnvironment实例。

5、EventLogger.setReporter(new EventLoggingReporter());
看源码说明,Set the reporter for event logging in libcore,简单就是说给lib库设置事件打印记者。

6、final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);

确保可信证书存储在正确的地方以便于查找CA证书。

7、Process.setArgV0("<pre-initialized>");
Process是管理系统流程的工具。setArgV0()是一个本地方法:

    /**     * Change this process's argv[0] parameter.  This can be useful to show     * more descriptive information in things like the 'ps' command.     *      * @param text The new name of this process.     *      * {@hide}     */    public static final native void setArgV0(String text);

8、Looper.prepareMainLooper();
终于开始干正事了,这里初始化了主线程。首先是在prepare()里面判断当前线程是否为空,因为Looper只允许有一个主线程。

public static void prepareMainLooper() {        prepare(false);        synchronized (Looper.class) {            if (sMainLooper != null) {                throw new IllegalStateException("The main Looper has already been prepared.");            }            sMainLooper = myLooper();        }    }    public static void prepare() {        prepare(true);    }    private static void prepare(boolean quitAllowed) {        if (sThreadLocal.get() != null) {            throw new RuntimeException("Only one Looper may be created per thread");        }        sThreadLocal.set(new Looper(quitAllowed));    }

9、ActivityThread thread = new ActivityThread();
thread.attach(false);

这里直接实例化了一个ActivityThread 对象,并调用了attach(false)。

private void attach(boolean system) {        sCurrentActivityThread = this;        mSystemThread = system;        if (!system) {            ViewRootImpl.addFirstDrawHandler(new Runnable() {                @Override                public void run() {                    ensureJitEnabled();                }            });            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",                                                    UserHandle.myUserId());            RuntimeInit.setApplicationObject(mAppThread.asBinder());            final IActivityManager mgr = ActivityManagerNative.getDefault();            try {                mgr.attachApplication(mAppThread);            } 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();                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.addConfigCallback(new ComponentCallbacks2() {            @Override            public void onConfigurationChanged(Configuration newConfig) {                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(newConfig, null)) {                        updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),                                mResourcesManager.getConfiguration().getLocales());                        // This actually changed the resources!  Tell                        // everyone about it.                        if (mPendingConfiguration == null ||                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {                            mPendingConfiguration = newConfig;                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);                        }                    }                }            }            @Override            public void onLowMemory() {            }            @Override            public void onTrimMemory(int level) {            }        });    }

有耐心的就看看。

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

判断当前主线程的Handler是否为空。

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

12、Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
跟前面的Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");相呼应,结束跟踪。

13、Looper.loop();
最重要的一句来了,前面Looper.prepareMainLooper()开启主线程,而这里的loop()就是处理主线程程序的关键段,所有通过Handler传到主线程的Message都会缓存在Looper的消息队列Queue里面,loop()里有个for(;;)循环,不断的从消息队列里面拿出消息进行处理,然后就有了事件的信息交流啦。

14、最后一句throw new RuntimeException("Main thread loop unexpectedly exited");
必要的异常处理语句。

最后说一句,若有任何问题和疑问,欢迎指正。

1 0
原创粉丝点击