源码分析 — ActivityThread(二)之相关类的分析


一、概述

《源码分析 — ActivityThread(一)之main()何时被调用》一文,我们知道了 ActivityThread.main() 被调用的时机;

本文对以下几个问题进行分析:

  1. ActivityThread.main() 方法中到底做了些什么操作呢?
  2. ApplicationThread
  3. H
  4. ActivityThread

源码版本: Andoroid 23

涉及到的知识点:

  1. 《源码分析 — Handler机制线程间通信》
  2. 《源码分析 — ActivityThread(一)之main()何时被调用》
  3. 《源码分析 — Binder机制(一)(进程间通信)》
  4. 《源码分析 — Binder机制(二)之IActivityManager》

二、ActivityThread.main() 方法

ActivityThread.main() 方法主要做了以下几个操作:

  1. 创建一个 Looper 对象,并绑定到当前线程;
  2. 创建一个 ActivityThread 对象,并执行 attach() 操作;
  3. 获取一个 Handler 对象,用于后面发送 MessageLooper 中;
  4. 启动 Looper 轮询器,让它从 MessageQueue 中获取 Message,从而在 sMainThreadHandler 中进行处理;
  5. 抛出 RuntimeException 异常,在 ZygoteInit.main() 方法中被捕获到后,关闭 Socket 连接;
// ActivityThread.class
public static void main(String[] args) {
    // ...代码省略...
    // 1.创建一个Looper对象,并绑定到当前线程;
    Looper.prepareMainLooper();

    // 2.创建一个ActivityThread对象,并执行attach()操作;
    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    // 3.获取一个Handler对象,用于后面发送Message到Looper中;
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    // 4.启动Looper轮询器,让它从MessageQueue中获取Message,从而在sMainThreadHandler中进行处理;
    Looper.loop();

    // 5.这里抛出RuntimeException异常,会在 ZygoteInit.main()方法中被捕获到,具体请看下面一段代码;
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

小结:

关于第 1,3,4 涉及到Handler机制,请参考《源码分析 — Handler机制线程间通信》
下面只针对第 2,5 两点进行分析;

2.1 执行 ActivityThread.attach() 操作

// system =false
private void attach(boolean system) {

    if (!system) {// 执行if代码块
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        // 获取到
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            /* 
             * ActivityManagerNative.getDefault()获取到的其实是ActivityManagerProxy对象,即IActivityManager接口的远程代理类;
             * 这里执行的是ActivityManagerProxy.attachApplication();
             * 最终通过Binder调用到ActivityManagerService.attachApplication();
             */
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            // Ignore
        }
    }
    // ...
}

小结:

  1. ActivityManagerNative.getDefault() 获取到的其实是 IActivityManager 接口的远程代理类 ActivityManagerProxy,被代理的远程服务端是 ActivityManagerService
  2. ActivityManagerProxy.attachApplication() 调用涉及到 Binder机制 ,请参考:
    1. 《源码分析 — Binder机制(一)(进程间通信)》
    2. 《源码分析 — Binder机制(二)之IActivityManager》

2.2 在 main() 最后为何要抛出 RuntimeException 异常呢?又是在哪里被捕获呢?

《源码分析 — ActivityThread(一)之main()何时被调用》一文中,我们知道了 ActivityThread.main() 被调用的时机;
因此可以在 ZygoteInit.main() 找到问题的答案;

// ZygoteInit.class
public static void main(String argv[]) {
    try {
        // ...
        runSelectLoop(abiList);
        closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
        caller.run();//这里执行ActivityThread.main()方法
    } catch (RuntimeException ex) {
        //这里接收ActivityThread.main()抛出的异常,从而执行关闭Socket的操作;
        closeServerSocket();
        throw ex;
    }
}

2.3 小结

ActivityThread.main() 最后一行抛出一个 RuntimeException 异常,
目的就是为了在 ZygoteInit.main() 中被捕获,从而关闭 Socket 通道;
其实在 SystemServer.run() 的最后一行也抛出了一个 RuntimeException 异常,原理相同;


三、ActivityThread、ApplicationThread、H(Handler)之间的关系

这里写图片描述

下表是这三个类中各方法的对应关系:

ApplicationThreadH(Handler)ActivityThread
bindApplication()H.BIND_APPLICATIONhandleBindApplication
scheduleLaunchActivity()H.LAUNCH_ACTIVITYhandleLaunchActivity()
schedulePauseActivity()H.PAUSE_ACTIVITYhandlePauseActivity()
scheduleStopActivity()H.STOP_ACTIVITY_HIDEhandleStopActivity()
scheduleDestroyActivity()H.DESTROY_ACTIVITYhandleDestroyActivity()
scheduleRelaunchActivity()H.RELAUNCH_ACTIVITYhandleRelaunchActivity()
scheduleCreateService()H.CREATE_SERVICEhandleCreateService()

下面针对 ApplicationThreadbindApplication()、scheduleLaunchActivity() 方法,及另两个类对应的方法进行分析;


四、类 ApplicationThread

4.1 代码分析

private class ApplicationThread extends ApplicationThreadNative {

        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, ...) {
            ActivityClientRecord r = new ActivityClientRecord();
            // token就是AMS的ActivityRecord中的appToken对象,用来保证每个Activity的唯一性;
            r.token = token;
            // ...

            // 发送一个LAUNCH_ACTIVITY消息到Handler的消息队列中;
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

        public final void bindApplication(String processName, ...) {
            // ...
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            // ...

            // 发送一个BIND_APPLICATION消息到Handler的消息队列中;
            sendMessage(H.BIND_APPLICATION, data);
        }
}

4.2 小结

  1. 由下面的表格可知:IApplicationThread、IActivityManager 接口的接口服务端和接口代理类分别对应的是什么;
  2. ActivityManagerService 和应用程序不是运行在同一个进程中,所以无法和应用进程直接进行通信,而是需要借助 Binder 来达到通信的目的;
  3. ApplicationThread 是运行在应用进程当中的,与ActivityThread 属于同一个进程;
  4. Binder 是单向通信的;
  5. ActivityManagerService 所在进程和应用进程间的通信:
    1. 应用进程访问ActivityManagerService 所在进程:通过 ApplicationThreadNative.asInterface() 获取到 IActivityManager 接口的远程服务代理类 ActivityManagerProxy,从而实现通信;
    2. ActivityManagerService 所在进程访问应用进程:通过 ActivityManagerNative.getDefault() 获取 IApplicationThread 接口的远程服务代理类 ApplicationThreadProxy,从而实现通信;
接口Client(客户端)Service(服务端)Proxy(远程代理类)Proxy的获取方式
IApplicationThreadApplicationThreadNativeApplicationThreadApplicationThreadProxyApplicationThreadNative.asInterface()
IActivityManagerActivityManagerNativeActivityManagerServiceActivityManagerProxyActivityManagerNative.getDefault()

五、类 H(Handler)

5.1 代码分析

private class H extends Handler {
    public static final int LAUNCH_ACTIVITY  = 100;
    public static final int BIND_APPLICATION = 110;
    // ...

    public void handleMessage(Message msg) {

        switch (msg.what) {
            case LAUNCH_ACTIVITY:
                //...
                // 执行ActivityThread.handleLaunchActivity()方法;
                handleLaunchActivity(r, null);
                break;

            case BIND_APPLICATION:
                AppBindData data = (AppBindData)msg.obj;
                // 执行ActivityThread.handleBindApplication()方法;
                handleBindApplication(data);
                break;  
        }
    }
}

5.2 小结

H 接收从 ApplicationThread 中发送出来的 Message,然后执行 ActivityThread 中对应的方法;


六、类 ActivityThread

6.1 代码分析

public final class ActivityThread {

    private void handleBindApplication(AppBindData data) {
        // ...省略大段代码...

        if (data.instrumentationName != null) {
            // ...省略大段代码...
            // 根据instrumentationName创建Instrumentation对象;
            ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            // ...
        } else {
            // 直接创建Instrumentation对象;
            mInstrumentation = new Instrumentation();
        }

        // 创建Application对象;
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        // 调用Application的onCreate()方法;
        mInstrumentation.callApplicationOnCreate(app);
    }

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // 
        Activity a = performLaunchActivity(r, customIntent);
        if (a != null) {
            // ...

            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
            // ...
        }
        // ...
    }
}

6.2 小结

ActivityThread 中存在一系列的方法,与 ApplicationThread 相对应;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值