Activity页面的绘制流程,内含福利

//省略部分代码

final ActivityClientRecord r = mActivities.get(token);

//省略部分代码

//调用Activity的performResume方法

r.activity.performResume(r.startsNotResumed, reason);

return r;

}

final void performResume(boolean followedByPause, String reason) {

//省略部分代码

//调用Instrumentation的callActivityOnResume方法

mInstrumentation.callActivityOnResume(this);

//省略部分代码

}

public void callActivityOnResume(Activity activity) {

activity.mResumed = true;

//调用Activity的onResume

activity.onResume();

if (mActivityMonitors != null) {

synchronized (mSync) {

final int N = mActivityMonitors.size();

for (int i=0; i

final ActivityMonitor am = mActivityMonitors.get(i);

am.match(activity, activity, activity.getIntent());

}

}

}

}

上面我们跟了一下performResumeActivity的源码,发现最后调用了Activity的onResume,由此我们可以知道在注释一的时候,Activity的onResume方法其实已经执行完成了,但是我们的界面绘制还没有开始呢,印证了我们开头说的。

2.下面我们来看看注释2这个wm到底是个什么东西呢,看看它的具体实现类是什么。

//Activity的getWindowManager方法

public WindowManager getWindowManager() {

return mWindowManager;

}

//mWindowManager是在Activity的attach方法中被创建的

//这个方法是handleResumeActivity前执行的分析启动流程的时候我们会说到

final void attach(Context context, ActivityThread aThread,

Instrumentation instr, IBinder token, int ident,

Application application, Intent intent, ActivityInfo info,

CharSequence title, Activity parent, String id,

NonConfigurationInstances lastNonConfigurationInstances,

Configuration config, String referrer, IVoiceInteractor voiceInteractor,

Window window) {

//调用setWindowManager方法

mWindow.setWindowManager(

(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),

mToken, mComponent.flattenToString(),

(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

if (mParent != null) {

mWindow.setContainer(mParent.getWindow());

}

//直接调用Window的getWindowManager方法

mWindowManager = mWindow.getWindowManager();

}

//Window的setWindowManager方法

public void setWindowManager(WindowManager wm, IBinder appToken, String appName,

boolean hardwareAccelerated) {

if (wm == null) {

wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);

}

//调用WindowManagerImpl的createLocalWindowManager方法创建mWindowManager对象

mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);

}

//Window的getWindowManager方法

public WindowManager getWindowManager() {

return mWindowManager;

}

//WindowManagerImpl的createLocalWindowManager创建的是一个WindowManagerImpl对象

public WindowManagerImpl createLocalWindowManager(Window parentWindow) {

return new WindowManagerImpl(mContext, parentWindow);

}

根据以上源码我们知道了注释2的vm其实就是WindowManagerImpl对象。注释1注释2这两个前菜已经给大家分析完了。下面我们进入主题Activity页面的绘制。

- (2)WindowManagerImpl.addView

通过前面的分析,我们可以知道注释3处其实就是调用了WindowManagerImpl的addView方法。下面我们来看看这个方法到底做了什么。

@Override

public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {

applyDefaultToken(params);

//调用WindowManagerGlobal的addView方法

mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);

}

//WindowManagerGlobal的addView

public void addView(View view, ViewGroup.LayoutParams params,

Display display, Window parentWindow) {

ViewRootImpl root;

View panelParentView = null;

1.创建ViewRootImpl对象

root = new ViewRootImpl(view.getContext(), display);

view.setLayoutParams(wparams);

mViews.add(view);

mRoots.add(root);

mParams.add(wparams);

// do this last because it fires off messages to start doing things

try {

2.调用ViewRootImpl的setView方法

root.setView(view, wparams, panelParentView);

} catch (RuntimeException e) {

// BadTokenException or InvalidDisplayException, clean up.

if (index >= 0) {

removeViewLocked(index, true);

}

throw e;

}

}

}

注释1是个很重要的点,这里创建了一个ViewRootImpl对象。

我们来解析一下这个ViewRootImpl里面需要关注的几个点。

我们先看看ViewRootImpl的构方法:

public ViewRootImpl(Context context, Display display) {

//获取Session对象

mWindowSession = WindowManagerGlobal.getWindowSession();

mDisplay = display;

mBasePackageName = context.getBasePackageName();

//主线程

mThread = Thread.currentThread();

//创建Choreographer对象,这个对象很重要,可以把它理解为一个Handler

//Android 16.6ms刷新一次页面它启到了主要作用

//我们马上看看这个Choreographer是个什么

mChoreographer = Choreographer.getInstance();

mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);

}

ViewRootImpl的构造方法里面我们暂时值关注两件事

1.获取了Session对象这个对象是我们与WindowManagerService交互的桥梁。

2.创建了Choreographer对象。

我们现来看看这个Choreographer对象到底是什么,为什么它那么重要呢?

public static Choreographer getInstance() {

return sThreadInstance.get();

}

// Thread local storage for the choreographer.

private static final ThreadLocal sThreadInstance =

new ThreadLocal() {

@Override

protected Choreographer initialValue() {

//注意了这里其实就是主线程的Looper

//ViewRootImpl对象就是在主线程创建的

Looper looper = Looper.myLooper();

if (looper == null) {

throw new IllegalStateException("The c

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

urrent thread must have a looper!");

}

//创建Choreographer对象

Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);

if (looper == Looper.getMainLooper()) {

mMainInstance = choreographer;

}

return choreographer;

}

};

private Choreographer(Looper looper, int vsyncSource) {

mLooper = looper;

//前面我们说了正常情况瞎这个looper对象就是主线程的looper对象

//所以通过这个Handler发送的消息都是在主线程处理的

mHandler = new FrameHandler(looper);

//创建FrameDisplayEventReceiver

//这个对象可以理解为一个任务

mDisplayEventReceiver = USE_VSYNC

? new FrameDisplayEventReceiver(looper, vsyncSource)
null;

mLastFrameTimeNanos = Long.MIN_VALUE;

mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());

//可以理解为绘制任务队列

mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];

for (int i = 0; i <= CALLBACK_LAST; i++) {

mCallbackQueues[i] = new CallbackQueue();

}

// b/68769804: For low FPS experiments.

setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1));

}

private final class FrameDisplayEventReceiver extends DisplayEventReceiver

implements Runnable {

private boolean mHavePendingVsync;

private long mTimestampNanos;

private int mFrame;

public FrameDisplayEventReceiver(Looper looper) {

super(looper);

}

//这个的onVsync方法是什么时候调用的呢?

//我们知道Android没16.6ms都会刷新一次屏幕,原理其实就是这个Vsync导致的

//这个Vsync信号是从底层传递上来的

//onVsync这个方法也是通过jni从底层调用上来,这个方法不会被java层调用

//每16.6ms调用一次

@Override

public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {

// Ignore vsync from secondary display.

// This can be problematic because the call to scheduleVsync() is a one-shot.

// We need to ensure that we will still receive the vsync from the primary

// display which is the one we really care about. Ideally we should schedule

// vsync for a particular display.

// At this time Surface Flinger won’t send us vsyncs for secondary displays

// but that could change in the future so let’s log a message to help us remember

// that we need to fix this.

mTimestampNanos = timestampNanos;

mFrame = frame;

Message msg = Message.obtain(mHandler, this);

msg.setAsynchronous(true);

//通过Handler把自身作为一个任务发送到主线程的消息队列去做处理

mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);

}

@Override

public void run() {

mHavePendingVsync = false;

//当绘制任务被处理时调用doFrame方法

doFrame(mTimestampNanos, mFrame);

}

}

void doFrame(long frameTimeNanos, int frame) {

if (frameTimeNanos < mLastFrameTimeNanos) {

if (DEBUG_JANK) {

Log.d(TAG, "Frame time appears to be going backwards. May be due to a "

  • “previously skipped frame. Waiting for next vsync.”);

}

scheduleVsyncLocked();

return;

}

//执行这一次队列中的绘制任务

Trace.traceBegin(Trace.TRACE_TAG_VIEW, “Choreographer#doFrame”);

AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);

mFrameInfo.markInputHandlingStart();

doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);

mFrameInfo.markAnimationsStart();

doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);

mFrameInfo.markPerformTraversalsStart();

doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);

doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);

}

void doCallbacks(int callbackType, long frameTimeNanos) {

CallbackRecord callbacks;

final long now = System.nanoTime();

//根据callbackType取出mCallbackQueues的任务

callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(

now / TimeUtils.NANOS_PER_MS);

if (callbacks == null) {

return;

}

synchronized (mLock) {

try {

Trace.traceBegin(Trace.TRACE_TAG_VIEW, CALLBACK_TRACE_TITLES[callbackType]);

//for循环执行需要绘制的任务

for (CallbackRecord c = callbacks; c != null; c = c.next) {

if (DEBUG_FRAMES) {

Log.d(TAG, “RunCallback: type=” + callbackType

  • “, action=” + c.action + “, token=” + c.token

  • “, latencyMillis=” + (SystemClock.uptimeMillis() - c.dueTime));

}

c.run(frameTimeNanos);

}

}

}

你可能感兴趣的:(程序员,面试,移动开发,android)