ActivityThread

ActivityThread

ActivityThread就是我们常说的主线程或UI线程,ActivityThread的main方法是整个APP的入口。

ActivityThread的初始化

ActivityThread类是Android APP进程的初始类,ActivityThread的main方法是一个APP的真正入口,MainLooper在它的main方法中被创建。

    //ActivityThread的main方法
    public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        //在attach方法中会完成Application对象的初始化,然后调用Application的onCreate()方法
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        ...
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

主线程Looper的初始化

Looper.prepareMainLooper()相关的代码如下:

    主线程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();
        }
    }
    
    普通线程Looper的初始化
    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));
    }

看过Handler源码就知道,主线程Looper的初始化和普通线程Looper的初始化很相似,但还是有以下几个区别

 1. 普通线程的Prepare()默认quitAllowed参数为true,表示允许退出,而主线程也就是ActivityThread的Looper参数为false,不允许退出。这里的quitAllowed参数,最终会传递给MessageQueue,当调用MessageQueue的quit方法时,会判断这个参数,如果是主线程,也就是quitAllowed参数为false时,会抛出异常。

    Looper的退时会判断quitAllowed
    void quit(boolean safe) {
        if (!mQuitAllowed) {
            throw new IllegalStateException("Main thread not allowed to quit.");
        }
        synchronized (this) {
            ...
        }
    }

2.我们注意到主线程Looper初始化之后,赋值给了成员变量sMainLooper,这个成员的作用就是向其他线程提供主线程的Looper对象。这下我们就应该知道为什么Looper.getMainLooper()方法能获取主线程的Looper对象。

    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper;
        }
    }

主线程Handler的初始化

在ActivityThread的main方法中我们注意到一行代码:

    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
见名知意,这是获取主线程的Handler,那么主线程的Handler是在什么时候初始化的呢?

    与之相关的代码如下:
    ActivityThread的成员变量
    final H mH = new H();
    
    final Handler getHandler() {
        return mH;
    }

从以上代码中可以看到,主线程的Handler作为ActivityThread的成员变量,是在ActivityThread的main方法被执行,ActivityThread被创建时而初始化,而接下来要说的ApplicationThread中的方法执行以及Activity的创建都依赖于主线程Handler。至此我们也就明白了,主线程(ActivityThread)的初始化是在它的main方法中,主线程的Handler以及MainLooper的初始化时机都是在ActivityThread创建的时候。

ApplicationThread及Activity的创建和启动

以上的代码和流程,就是对 MainLooper 和 ActivityThread 的初始化,我们接下来看一下 ActivityThread 的初始化及其对应的 attach 方法,在thread.attach方法中,ActivityManagerService通过attachApplication方法,将ApplicationThread对象绑定到ActivityManagerService,ApplicationThread是ActivityThread的私有内部类,实现了IBinder接口,用于ActivityThread和ActivityManagerService的所在进程间通信。

    ActivityThread的attach方法:
    private void attach(boolean system) {
        ...
        if (!system) {
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }else{
                ...
            }
        }
    }
    
    ActivityManagerService中的方法:
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
    
    这里的个人理解是:在每个ActivityThread(APP)被创建的时候,
    都需要向ActivityManagerService绑定(或者说是向远程服务AMS注册自己),
    用于AMS管理ActivityThread中的所有四大组件的生命周期。

上述AMS的代码中attachApplicationLocked方法比较复杂,主要功能有两个,详见注释,这里忽略了很多代码细节,具体的流程可以看源码

    AMS中的方法,主要功能有以下两步
    private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        ...
        主要用于创建Application,用调用onCreate方法
		thread.bindApplication(...);
		...
		主要用于创建Activity
        if (mStackSupervisor.attachApplicationLocked(app)) {
            ...
        }
    }

thread.bindApplication:主要用于创建Application,这里的thread对象是ApplicationThread在AMS中的代理对象,所以这里的bindApplication方法最终会调用ApplicationThread.bindApplication()方法,该方法会向ActivityThread的消息对应发送BIND_APPLICATION的消息,消息的处理最终会调用Application.onCreate()方法,这也说明Application.onCreate()方法的执行时机比任何Activity.onCreate()方法都早。

    ActivityThread中的bindApplication方法
    public final void bindApplication(...) {
        ...
        该消息的处理,会调用handleBindApplication方法
        sendMessage(H.BIND_APPLICATION, data);
    }
    ActivityThread中的handleBindApplication方法
    private void handleBindApplication(AppBindData data) {
        ...
        try {
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
            ...
            try {
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
            }
        } finally {
        }
    }
        
    LoadedApk中的方法,用于创建Application
    public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
        如果存在Application的实例,则直接返回,这也说明Application是个单例
        if (mApplication != null) {
            return mApplication;
        }

        Application app = null;
        ...这里通过反射初始化Application

        if (instrumentation != null) {
            try {
                调用Application的onCreate方法
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
            }
        }
        return app;
    }

mStackSupervisor.attachApplicationLocked(app):用于创建Activity,mStackSupervisor是AMS的成员变量,为Activity堆栈管理辅助类实例,该方法最终会调用ApplicationThread类的scheduleLaunchActivity方法,该方法也是类似于第一步,向ActivityThread的消息队列发送创建Activity的消息,最终在ActivityThread中完成创建Activity的操作。

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        ...
        if (realStartActivityLocked(hr, app, true, true)) {
            ...
        }          
        ...
    }

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        try {
            调用ApplicationThread的scheduleLaunchActivity用于启动一个Activity
            app.thread.scheduleLaunchActivity(...);
        } catch (RemoteException e) {
        }
    }

    ApplicationThread的scheduleLaunchActivity方法会向ActivityThread发送LAUNCH_ACTIVITY信息,用于启动一个Activity,该消息的处理会调用ActivityThread的handleLaunchActivity方法,最终启动一个Activity

以上就是从ActivityThread的main方法执行到Activity的创建之间的流程。

转载文章:https://blog.csdn.net/hzwailll/article/details/85339714

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值