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

本文详细分析了Android Activity的启动流程,从ActivityThread的Main方法入手,涉及Looper初始化、AMS与Binder机制、Application与Activity的创建过程,直至onCreate、onStart和onResume方法的调用。通过源码解读,揭示了Activity启动的内部机制。
摘要由CSDN通过智能技术生成

前言

关于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");
    }

通过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();
            }
            ....
    }

先看下,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;
                }
            };

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 != 
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值