Android源码解析系列1——Activity启动和界面加载

源码版本:Android 27

一、应用的启动

首先我们需要知道:

ActivityThreadmain方法,是Android应用程序启动时的入口点。

 

public final class ActivityThread {
    // 省略部分代码

    public static void main(String[] args) {
        // 省略部分代码

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

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

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

        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}

在main方法里执行了以下操作:

  • 1、首先调用了Looper.prepareMainLooper()方法,它会创建一个与当前线程(主线程)相关联的Looper对象。
  • 2、然后创建一个ActivityThread对象,并调用其attach()方法。
  • 3、最后调用Looper.loop()方法,让刚创建的Looper对象,从它的MessageQueue中循环读取数据并执行。

现在,我们开始分析ActivityThreadattach()方法做了什么?

 

public final class ActivityThread {
    final ApplicationThread mAppThread = new ApplicationThread();
    // 省略部分代码

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            // 省略部分代码

            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // 省略后续代码
        }
    }
}

attach方法中,调用ActivityManager.getService()方法,获取到远程的IActivityManager对象,并将一个ApplicationThread实例传入。

ApplicationThread继承至IApplicationThread.Stub,即Binder进程间通信的本地实现类。它有很多与Activity生命周期相关的方法,大都以schedule开头:

至此,我们可以总结一下:

1、ActivityThreadmain方法,是应用程序启动的入口。
2、Activity生命周期是由系统底层控制,通过Binder机制,回调到ApplicationThreadscheduleXXX方法中。
3、ActivityThreadApplicationThread针对每个应用,都只有一个实例。

这里有个问题:
为什么没看到scheduleStartActivity方法?难道Activity的onStart()生命周期回调,不是由ActivityManager发送消息控制的?

带着这个疑问,我们开始阅读这些scheduleXXX方法的源码。

二、Activity生命周期

我们从ApplicationThread中的scheduleLaunchActivity方法开始分析,因为由名字可以猜测它应该会执行Activity创建和启动工作。

 

public final class ActivityThread {
    // 省略部分代码

    private class ApplicationThread extends IApplicationThread.Stub {
        // 省略部分代码

        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            // 给ActivityClientRecord赋值

            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
        // 省略部分代码
    }
}

scheduleLaunchActivity方法中,首先创建了一个ActivityClientRecord对象,并对其进行赋值。然后通过Handler,将线程由Binder线程切换到主线程。最终调用到ActivityThreadhandleLaunchActivity方法。

注意:ActivityClientRecord主要用于记录与Activity相关的数据。

 

public final class ActivityThread {
    // 省略部分代码

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        // 省略部分代码

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            // 省略部分代码
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

           if (!r.activity.mFinished && r.startsNotResumed) {
                // The activity manager actually wants this one to start out paused, because it
                //
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如意号。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值