当前位置:   article > 正文

Android进阶3:Activity源码分析(1) —— Activity启动流程(8.0)_android 深入分析activity源码

android 深入分析activity源码

前言

关于Activity的源码分析,看了足足有半个月,理由就是:
1:Activity源代码很多,逻辑很复杂
2:下班再能加班学习,礼拜天抽空学习源码
至于为什么看源码:因为偶尔看到一句话:不懂Activity的onCreate的内部源码,你敢说你是Android开发程序猿?!

其实关于这篇文章,我想了很久,不太敢贸然写,因为牵涉的类有点多并且复杂,怕理解出错,给各位小伙伴带来困扰,经过学习了两个礼拜,学到了一点东西,总结一下。
首先Activity的启动切入点有两个,startActivity切入和ActivityThread的main方法切入,最终的效果都是开启一个新的Activity。 本篇文章先从ActivityThread的main方法切入分析。

ActivityThread的Main方法入口

通常我们启动一个App,首先都是先创建一个进程,然后AMS调度,进入到ActivityThread的main方法中,ActivityThread类通常就是我们说的UI线程(主线程),一个进程对应一个ActivityThread,用于调度Activity的生命周期,Service的生命周期,以及调度Instrumentation的创建。看下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>");

        //注意点1:创建主线程的Looper
        Looper.prepareMainLooper();

        //创建ActivityThread类
        ActivityThread thread = new ActivityThread();
        //注意点2:
        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();

        //注意点3:不能够退出主线程Looper
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

通过Main方法,看下三个注意点:

  1. 创建主线程的Looper对象;在之前学习Handler,Looper源码的时候,没有初始化Looper,都能够实现消息调度。
  2. 调用了ActivityThread的attach方法
  3. 不能够退出主线程UI,如果如果退出,就报错,因为我们知道,开启looper消息循环之后,Looper.loop()之后的代码是不会执行的,因为如果退出了主线程,那么App自动就死了,所以就提示报错。

进入ActivityThread的attach方法。

    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());
            //创建获得IActivityManager的代理对象ActivityManagerService
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //创建applicaiton
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ....
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

先看下,ActivityManager.getService(),进入该方法:

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    //单例模式
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    //获取一个关联了系统服务ActivityManagerService的Binder对象
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    //获取IActivityManager的代理对象,基于binder机制,通过调用代理对象的方法,从而使ActivityManagerService对象的方法被调用.
                    //注意:ActivityManagerService继承自IActivityManager.Stub。
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

getService()内部调用的是IActivityManagerSingleton的get方法,大体来说,IActivityManagerSingleton是一个单例对象,再看onCreate方法,方法内部首先通过ServiceManager获得Activity_Service的注册服务。返回IBinder对象,至此,我们应该知道了,其实和底层交互数据的原理就是Binder机制。

先说下Binder机制,我们知道Binder机制由四部分组成:客户端,服务端,ServiceManager管理以及Binder驱动。其中前三个运行在用户层,Binder驱动运行在内核层,然后服务端实现IBinder方法,成为代理对象,底层的各种的ManagerService都会在ServiceManager,通过ServiceManager统一获得各种服务端Binder对象。至于Binder机制,建议各位同学去看下Binder源码。在此不再赘述。

我们知道ActivityManagerService继承字IActivityManager.Stub,所以本身来说他就是一个Binder对象。所以getService()方法本身返回的就是一个代理对象,通过调用代理对象的方法,从而调用AMS(ActivityManagerService的简称)的方法。

接下来回到attach方法,调用了AMS的attachApplication方法,源码示下:

    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        ......
            if (app.instr != null<
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/680273
推荐阅读
相关标签
  

闽ICP备14008679号