Android 深度解析Activity启动流程与子线程更新UI

我们知道现在大多数的GUI框架都是采用单线程模型来处理消息队列和UI更新的,Android自然也是如此。

启动在APK首次启动的时候,Zygote进程会fork个子进程,并在子进程中调用ActivityThread的main函数,主线程的消息队列和ActivityThread实例的初始化都是在此完成的。
与AMS的通信ActivtyManagerService控制着Activity的启动与生命周期,并通过ApplicationThread与ActivityThread进行IPC通信。
onCreateAMS通过ApplicationThread的scheduleLaunchActivity启动一个新的Activity,并通过Handler调用ActivityThread的handleLaunchActivity方法。private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...... 
    Activity a = performLaunchActivity(r, customIntent); 
    if (a != null) { 
        r.createdConfig = new Configuration(mConfiguration); 
        Bundle oldState = r.state; 
        handleResumeActivity(r.token, false, r.isForward, 
            !r.activity.mFinished && !r.startsNotResumed); 
    ...... 


private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 
    ...... 
    if (r.isPersistable()) { 
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 
    } else { 
        mInstrumentation.callActivityOnCreate(activity, r.state); 
    } 
    ...... 


Instrumentation.java 
public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { 
    prePerformCreate(activity); 
    activity.performCreate(icicle, persistentState); 
    postPerformCreate(activity); 


Activity.java 
final void performCreate(Bundle icicle, PersistableBundle persistentState) { 
    onCreate(icicle, persistentState); 
    mActivityTransitionState.readState(icicle); 
    performCreateCommon(); 


onResumeActivtyThread通过performLaunchActivity的调用做些Activity的初始化,包括创建实例和最终调用Activity的onCreate方法。之后通过调用handleResumeActivity方法final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { 
    ...... 
    // TODO Push resumeArgs into the activity for consideration 
    ActivityClientRecord r = performResumeActivity(token, clearHide); 
    ...... 
    if (r.window == null && !a.mFinished && willBeVisible) { 
        if (a.mVisibleFromClient) { 
            a.mWindowAdded = true; wm.addView(decor, l); 
        } 
    } 
    ...... 

public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide) { 
    ...... 
    r.activity.performResume(); 
    ...... 

ActivtyThread通过handleResumeActivity调用Activity的onResume方法之后,并在当前Activity的Window为null等情况下,调用WindowMangerGlobal的addView方法将Activity的decorView添加在Window中。WindowMangerGlobal.java 
public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) { 
    ...... 
    root = new ViewRootImpl(view.getContext(), display); 
    view.setLayoutParams(wparams); 
    try { 
        root.setView(view, wparams, panelParentView); 
    } catch (RuntimeException e) { 
    ...... 
}重点来了,在Activity的onCreate和onResume调用之后,ActivityThread才创建了ViewRootImpl,并调用setView方法ViewRootImpl.java 
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { 
    ...... 
    requestLayout(); 
    ...... 
    view.assignParent(this); 
    ...... 


@Override 
public void requestLayout() { 
    if (!mHandlingLayoutInLayoutRequest) { 
        checkThread(); 
        mLayoutRequested = true; scheduleTraversals(); 
    } 


void invalidate() { 
    mDirty.set(0, 0, mWidth, mHeight); 
    if (!mWillDrawSoon) { 
        scheduleTraversals(); 
    } 
}在此才会检查当前线程是否为主线程,并设置了view的parent,之后一些系统view组件或自定义view会通过调用requestlayout或者invalidate实现view的重新渲染(scheduleTraversals通过Handelr实现)。
结论通过上诉Activity的启动过程可知,我们在Activity的onCreate和onResume中,通过子线程的确可以实现更新某些系统view组件。@Override 
protected void onResume() { 
    super.onResume(); 
    new NoUIThread().start(); 


class NoUIThread extends Thread { 
    
    @Override 
    public void run() { 
        mNoUITextView.setText("Penner"); 
    }
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值