View的绘制流程

关于View的绘制流程的文章:

Android应用层View绘制流程与源码分析

Android中View绘制流程浅析

以下源码使用的是android源码4.0.4:

我们都清楚Activity中onCreate()方法在setContentView()后,View的宽高是获取不到的。同时我们知道Activity在onResume()后才完全可见,并且初次在onResume()方法中也是拿不到View的尺寸的,这样可以推算得出:View的绘制流程是在onResume()方法执行结束后才开始的。那Activity的生命周期方法背后是由谁,又何时调用的?

答:ActivityManagerService 

ActivityManagerService(以下简称AMS))是Androids上层系统中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。

相对而言ActivityThread的main方法是应用程序的入口,main()方法里做一些初始化工作,其中包括和AMS建立起通信。

ActivityThread.java.main()

public static void main(String[] args) {
		
	 final ApplicationThread mAppThread = new ApplicationThread();
    final Looper mLooper = Looper.myLooper();
    final H mH = new H();
    final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
    
	//初始化lopper
    Looper.prepareMainLooper();

	//初始化ActivityThread
    ActivityThread thread = new ActivityThread();
	 //ApplicationThread和AMS建立联系
    thread.attach(false);

	//取消息
    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace Looper.loop();.TRACE_TAG_ACTIVITY_MANAGER);
   
	//loop()方法如果执行结束,未能取到消息,程序抛出异常退出。
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

以下是 ActivityThread.java.attach(boolean system)

private void attach(boolean system) {
        if (!system) {
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
            	...
                mgr.attachApplication(mAppThread);
                ,,,
            } catch (RemoteException ex) {
                // Ignore
            }
        } 
        
}

然后是ActivityManagerNative.java

private IBinder mRemote;
public void attachApplication(IApplicationThread app) throws RemoteException{
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
}
 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {
		switch (code) {
			case ATTACH_APPLICATION_TRANSACTION: {
				...
	            IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder());
	            if (app != null) {
	                attachApplication(app);
	            }
	            ...
	            return true;
	        }
		}
		
 }

 

ActivityThread会管理和用户打交道的Activity,应用所有的Activity都存在ActivityThread中的mActivities集合中,而ActivityThread响应AMS的号召,需要借助ApplicationThread来接受这个诏令,点进去看全都是生命周期方法。接着调用attach()方法让ApplicationThread和AMS建立联系。H类就是一个Handler类,用于发送生命周期改变的消息,通知响应操作。

private class ApplicationThread extends IApplicationThread.Stub {

    //通知相应的进程执行启动Activity的操作
    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) {

        sendMessage(H.LAUNCH_ACTIVITY, r);
    }
    public final void scheduleResumeActivity(IBinder token, int processState,
            boolean isForward, Bundle resumeArgs) {

        sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq);
    }
    //.....

}

当Activity启动时会先调用到scheduleLaunchActivity()方法,由Handler发送通知消息后执行handleLaunchActivity()->performLaunchActivity()->callActivityOnCreate()->Activity.onCreate()。

private class H extends Handler {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                ...
                //该方法中会执行Activity的onCreate()方法。
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                ...
            } break;
            //onResume();
             case RESUME_ACTIVITY:
                ...
                handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
                        args.argi3, "RESUME_ACTIVITY");
                ...
                break;
        }
    }
}

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	...
	Activity a = performLaunchActivity(r, customIntent);
	...
}

Instrumentation mInstrumentation;
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	...
	mInstrumentation.callActivityOnCreate(activity, r.state);
	...
}

Instrumentation.java
 public void callActivityOnCreate(Activity activity, Bundle icicle) {
	...
	activity.performCreate(icicle);
	...
 	}

Activity.java
final void performCreate(Bundle icicle) {
        onCreate(icicle);
        ...
}

protected void onCreate(Bundle savedInstanceState) {
	...
	}

然后是onResume()的方法:

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ActivityClientRecord r = mActivities.get(token);

    //.............

    //执行onResume()方法
    r = performResumeActivity(token, clearHide, reason);

     if (r != null) {
        final Activity a = r.activity;
         if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;

            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    //将DecorView添加到Window上
                    wm.addView(decor, l);
            } 
        }
    //说法二:执行makeVisible()来添加View,但也是添加到Window里和上面一样的操作。清楚的小伙伴可以告诉我下。
    if (r.activity.mVisibleFromClient) {
            r.activity.makeVisible();
        }
    }
}

onResume()时也一样,当Activity的状态发生改变,经过层层调用执行到handleResumeActivity()方法,在方法中先调用Activity.onResume()方法,再执行WindowManager的addView()方法将Activity的根View(DecorView)添加上去,进而开始绘制流程。这就解释了为什么初次在onResume()方法中获取不到View的宽高。对DecorView不太明白的可以参考 Activity中setContentView浅析。而WindowManager实现类为WindowManagerImpl,WindowManagerImpl中addView()方法如下。原文
 

WindowManagerImpl.java

ViewRootImpl root;
private void addView(View view, ViewGroup.LayoutParams params,CompatibilityInfoHolder cih, boolean nest) {
	...
	root.setView(view, wparams, panelParentView);
}


ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
	...
	requestLayout();
	...
}

public void requestLayout() {
        checkThread();
        mLayoutRequested = true;
        scheduleTraversals();
    }

requestLayout()方法走下去会异步执行performTraversals()方法,View的三大流程都是在该方法中执行的。到这儿我们算是明白View的绘制流程是从哪儿开始的,接下来分析这个过程到底是怎么做的。

public void scheduleTraversals() {
     ...
     sendEmptyMessage(DO_TRAVERSAL);
     ...
    }

case DO_TRAVERSAL:
	performTraversals();


private void performTraversals() {
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值