Android应用启动,Activity加载及UI绘制流程详解

本文详细探讨了Android应用程序的启动流程,从ActivityThread的main方法开始,揭示了Activity启动、状态变更如何通过Handler消息机制进行。接着,文章剖析了setContentView的内部工作原理,包括PhoneWindow如何初始化DecorView和加载布局。最后,文章阐述了UI的绘制流程,从handleResumeActivity到ViewRootImpl的setView,逐步展示了测量、布局和绘制的完整过程。
摘要由CSDN通过智能技术生成

1.Android程序流程

           众所周知,我们的java程序想要开启需要依赖于main方法,也就是我们的程序入口(主线程)进入,但是在我们日常开发android程序的过程当中我们并没有发现main方法的存在,那么android当中的是如何开始运行的?

        熟悉的朋友们可能都知道在android当中存在一个叫做ActivityThread的类,这个类代表的是android当中的主线程,而在这个类当中我们看到了比较熟悉的main方法,那么现在是否可以认为我们的android在打开app时是首先调用的是当前这个类的main,也就是此处为我们的启动点:

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    这里省略掉部分代码...............
    Looper.prepareMainLooper();//这里开启主线程的Looper创建

    ActivityThread thread = new ActivityThread();//主函数再次开启一个Activity线程
    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();//这里开启主线程的消息轮训

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

OK,我们开始进入thread.attach(false)这个方法中查看做了什么:

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
    这里省略掉部分代码...............
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        //这个IActivityManager是Activity管理接口,
        final IActivityManager mgr = ActivityManager.getService();那么这个mgr得到的到底是什么?继续看下一步
        try {
        //这里调用attachApplication()这个方法
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
       
    } else {
       这里省略掉部分代码...............
    }

    // add dropbox logging to libcore
    DropBox.setReporter(new DropBoxReporter());

  
}

进入ActivityManager中查看getService()这个方法:

/**
 * @hide
 */
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

在这个当中,里面调用了的系统的ActivityManagerService这个服务,并且给出了一个Binder接口

了解Binder机制的小伙伴看到这里应该很眼熟,在图中的create方法中进行了一个跨进程的相关操作

1:获得系统的IBinder的实现类
2:将系统(服务端)的Binder对象转换成客户端可以使用的接口类对象


也就是说getService这个方法所返回的对象其实就是和系统进行跨进程通信的,从对象的类名称可知是Activity的管理类。mgr通过attachApplication方法和mAppThread进行了绑定,mAppThread的类是ApplicationThread,父类为IApplicationThread.Stub,和Binder中的Stub的作用一样,用来接收系统(服务端)发过来的跨进程消息。这也是为什么我们讲Activity是跨进程访问的原因。

attachApplication方法另外一个作用是在这里的作用其实实际上是ActivityThread通过attach获取到后,然后将applciationThread将其关联,把activity相关信息存储在applciationThread里面,apllicationThread的类为activity的各种状态做了相对应的准备工作。如下为attachApplication方法的具体源码:

这个时候我们需要关注,ApplicationThread(ApplicationThread这个类是在ActivityThread中的内部类)当中做了什么?

当我们打开ApplicationThread中我们会看到一堆的schedle方法,这些方法的名称其实就可以给我们表明,代表的是在执行Activity的某种状态时调用的计划执行方法,这时我们会看到一个scheduleLaunchActivity方法,表示计划加载时调用的。这里我们发现了一个很有意思的事情:

@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();//这个对象就是我们的Activity
    r.token = token;
    r.ident = ident;
    r.intent = intent;
    //...一系列的赋值操作
    updatePendingConfiguration(curConfig);

    sendMessage(H.LAUNCH_ACTIVITY, r);//将当前我们创建的Activity发送了出去
}

当走到这里我们会发现最终我们调用的是Handler的消息通信机制,也就是说,在这里我们可以总结一下,当Activity状态改变时,都会有对应的一个消息发送出去,而接收这里,我能发现通过发送时不同的状态,这边调用了不同的handlerXXXActivity方法。

在ActivityThread类中有一个Handler类名为H,该类就是用来处理不同的发送消息,以便改变Activity状态等操作的,如下:

public vo
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值