前言
为了描述Activity&Window&ViewRootImpl的关系,我们分别从以下三个阶段进行分析:
- Activity的启动流程;
- Activity的onCreate()阶段;
- Activity的resume流程;
一、Activity启动流程
在Activity启动流程分析中分析过,App进程创建后,会在ActivityThread的performLaunchActivity()方法中会创建Activity实例。
1.1 ActivityThread.performLaunchActivity
在ActivityThread.performLaunchActivity()执行流程中,和Window相关的代码从attach()方法开始分析:
public final class ActivityThread extends ClientTransactionHandler {
private Activity performLaunchActivity(ActivityThread.ActivityClientRecord r, Intent customIntent) {
Activity activity = null;
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// 省略部分代码;从Activity的attach()方法开始分析
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
}
}
1.2 Window & PhoneWindow
attach()方法中会涉及到创建Window。Window 是个抽象类,其具体实现类是 PhoneWindow,Activity 和 Dialog 中的 Window 对象都是 PhoneWindow。
在Activity的attach()方法内创建了PhoneWindow对象,然后PhoneWindow内创建了WindowManager(WindowManager用来与系统进程system_server通信):
public class Activity {
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token ...) {
// 创建 PhoneWindow 对象
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setCallback(this);
// 创建 WindowManagerImpl 对象
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindowManager = mWindow.getWindowManager();
}
}
在mWindow.setWindowManager()方法内会创建WindowManager对象,代码分析如下。
1.3 WindowManager & WindowManagerImpl
WindowManager是个接口,WindowManagerImpl其具体实现。每个Activity对应一个WindowManagerImpl。
public abstract class Window {
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
if (wm == null) {
wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
}
WindowManagerImpl中有个WindowManagerGlobal,所有WindowManagerGlobal都是用了这个单例,后面会涉及到:
public final class WindowManagerImpl implements WindowManager{
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
}
1.4 总结
Activity的启动过程中,在ActivityThread的performLaunchActivity()方法中会创建Activity实例,接着Activity的attach()方法内会创建PhoneWindow,接着PhoneWindow会创建WindowManagerImpl,在创建WindowManagerImpl时会将mToken(IBinder类型)传给WindowManagerImpl,系统服务WindowManagerService和WindowManagerImpl就是通过mToken(IBinder类型)用Binder机制进行互相通信的。
二、Activity的onCreate()阶段
在自定义Activity时,我们一般会在Activity的onCreate()方法内调用setContentView(),将layout布局设置给Activity:
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
接下来,主要来看下这个过程有哪些涉及到Window的地方。
2.1 setContentView()
在Activty的setContentView()方法内会调用PhoneWindow的setContentView()方法,PhoneWindow的setContentView()方法内会创建DecorView:
public class Activity {
public void setContentView(@LayoutRes int layoutResID) {
// 调用PhoneWindow的setContentView(),PhoneWindow内会创建DecorView
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
}
PhoneWindow的setContentView()方法内创建DecorView的代码如下:
public class PhoneWindow extends Window implements MenuBuilder.Callback {
public void setContentView(int layoutResID) {
// 省略...
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
}
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor(-1);
} else {
mDecor.setWindow(this);
}
}
protected DecorView generateDecor(int featureId) {
// 省略...
return new DecorView(context, featureId, this, getAttributes());
}
}
2.2 总结
在Activty的setContentView()方法内会调用PhoneWindow的setContentView()方法,PhoneWindow的setContentView()方法内会创建DecorView,之后PhoneWindow和DecorView彼此关联。
三、Activity的resume流程
与Activity启动流程类似,Activity的resume流程也会经历系统进程然后调用到ActivityThread,下面首先来看下ActivityThread.handleResumeActivity()的逻辑。
3.1 ActivityThread.handleResumeActivity()
在ActivityThread.handleResumeActivity()中,主要分析两个部分:(1)WindowManagerGlobal内创建ViewRootImpl;(2)WindowManager与DecorView相关联的过程。 重点了解第一个部分,第二个部分简单了解即可。
public final class ActivityThread {
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
final android.app.ActivityThread.ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
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();
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 1.内部会调用WindowManagerGlobal创建ViewRootImpl
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
}
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
ViewRootImpl impl = r.window.getDecorView().getViewRootImpl();
if (r.activity.mVisibleFromClient) {
// 2.将启动流程中创建的WindowManager与onCreate阶段创建的DecorView关联起来
r.activity.makeVisible();
}
}
Looper.myQueue().addIdleHandler(new android.app.ActivityThread.Idler());
}
}
3.2 WindowManagerImpl
在第一章的Activity启动流程中分析过,启动流程中会创建一个PhoneWindow和一个WindowManagerImpl,每个Activity对应一个WindowManagerImpl。WindowManagerImpl内持有WindowManagerGlobal单例。
public final class WindowManagerImpl {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
mContext.getUserId());
}
}
3.2.1 WindowManagerGlobal
WindowManagerGlobal是单例类,且调用系统服务的相关代码WindowManagerGlobal.getWindowManagerService()、WindowManagerGlobal.getWindowSession()也是单例实现:
public final class WindowManagerGlobal {
public static WindowManagerGlobal getInstance() {
synchronized (WindowManagerGlobal.class) {
if (sDefaultWindowManager == null) {
sDefaultWindowManager = new WindowManagerGlobal();
}
return sDefaultWindowManager;
}
}
public static IWindowManager getWindowManagerService() {
synchronized (WindowManagerGlobal.class) {
if (sWindowManagerService == null) {
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
try {
if (sWindowManagerService != null) {
ValueAnimator.setDurationScale(
sWindowManagerService.getCurrentAnimatorScale());
sUseBLASTAdapter = sWindowManagerService.useBLAST();
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
return sWindowManagerService;
}
}
public static IWindowSession getWindowSession() {
synchronized (WindowManagerGlobal.class) {
if (sWindowSession == null) {
try {
InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
});
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
return sWindowSession;
}
}
}
WindowManagerGlobal单例类内管理着所有DecorView,ViewRootImpl也是在WindowManagerGlobal.addView()内完成创建的,代码分析如下:
public final class WindowManagerGlobal {
// 所有view
private final ArrayList<View> mViews = new ArrayList<View>();
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
private final ArrayList<WindowManager.LayoutParams> mParams =
new ArrayList<WindowManager.LayoutParams>();
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId) {
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// 1.创建ViewRootImpl
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
// 2.把decorView放入list
mViews.add(view);
// 3.把ViewRootImpl放入list
mRoots.add(root);
mParams.add(wparams);
// 4.ViewRootImpl内创建SurfaceHolder,并调用系统服务进程创建Surface与SurfaceFlinger
root.setView(view, wparams, panelParentView, userId);
}
}
public static IWindowSession getWindowSession() {
synchronized (android.view.WindowManagerGlobal.class) {
if (sWindowSession == null) {
try {
InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();
IWindowManager windowManager = getWindowManagerService();
// 调用系统服务WindowManagerService,系统服务进程会创建 Surface 与 SurfaceFlinger
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
});
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
return sWindowSession;
}
}
}
3.2.2 ViewRootImpl
ViewRootImpl是一个很常见的类了,ViewRootImpl不是一个View,我们所熟悉的View绘制流程中的performMeasure()、performLayout()、performDraw()都是在performTraversals()方法中顺序调用的。本次不涉及到绘制流程分析,只分析ViewRootImpl创建过程中做了哪些操作。
ViewRootImpl创建过程中,创建了SurfaceHolder,并调用系统服务进程WindowManagerService,系统服务进程会创建Surface与SurfaceFlinger:
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
public ViewRootImpl(Context context, Display display) {
// 获取 IWindowSession 的代理类
this(context, display, android.view.WindowManagerGlobal.getWindowSession(),
false /* useSfChoreographer */);
}
public ViewRootImpl(Context context, Display display, IWindowSession session,
boolean useSfChoreographer) {
mContext = context;
// 默认值是WindowManagerGlobal单例的WindowManagerGlobal.getWindowSession()
mWindowSession = session;
mDisplay = display;
mBasePackageName = context.getBasePackageName();
mThread = Thread.currentThread();
mWindow = new android.view.ViewRootImpl.W(this);
mChoreographer = useSfChoreographer
? Choreographer.getSfInstance() : Choreographer.getInstance();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
}
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
synchronized (this) {
if (mView == null) {
mView = view;
if (view instanceof RootViewSurfaceTaker) {
mSurfaceHolderCallback =
((RootViewSurfaceTaker)view).willYouTakeTheSurface();
if (mSurfaceHolderCallback != null) {
// 1.创建SurfaceHolder
mSurfaceHolder = new android.view.ViewRootImpl.TakenSurfaceHolder();
mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
mSurfaceHolder.addCallback(mSurfaceHolderCallback);
}
}
// 2.首次执行layout,内部会调用performTraversals()
requestLayout();
// 3.mWindowSession会调用系统服务WindowManagerService,系统服务进程会创建Surface与SurfaceFlinger
res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mDisplayCutout, inputChannel,
mTempInsets, mTempControls);
setFrame(mTmpFrame);
}
}
}
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
// 添加同步屏障
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 把mTraversalRunnable添加到mChoreographer
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
// 移除同步屏障
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
// 执行绘制流程
performTraversals();
}
}
private void performTraversals() {
if (!mStopped || mReportNextDraw) {
boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
(relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
|| mHeight != host.getMeasuredHeight() || dispatchApplyInsets ||
updatedConfiguration) {
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
// 1.measure流程
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
layoutRequested = true;
}
}
final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
boolean triggerGlobalLayoutListener = didLayout
|| mAttachInfo.mRecomputeGlobalAttributes;
if (didLayout) {
// 2.layout流程
performLayout(lp, mWidth, mHeight);
}
boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
if (!cancelDraw) {
// 3.draw流程
performDraw();
}
}
}
Handler中同步屏障的含义就是同步消息的屏障,在handler设置了同步屏障后,在取message时如果有同步屏障,会先把异步消息都处理完后才开始处理同步消息。
3.3 Activity.makeVisible()
将启动流程中创建的WindowManager与onCreate阶段创建的DecorView关联起来的代码比较简单:
public class Activity {
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
}
3.4 总结
- 在Activity的启动流程中,会创建一个PhoneWindow和一个WindowManagerImpl,每个Activity对应一个WindowManagerImpl。
- 在Activty的setContentView()方法内会调用PhoneWindow的setContentView()方法,PhoneWindow的setContentView()方法内会创建DecorView:
- 在Activity的resume流程中,会调用WindowManagerGlobal创建ViewRootImpl,接着ViewRootImpl会创建SurfaceHolder,并通过WindowManagerGlobal.getWindowSession()调用系统服务WindowManagerService创建Surface与SurfaceFlinger;
- 每个PhoneWindow都持有WindowManagerGlobal单例,WindowManagerGlobal管理着所有的ViewRootImpl和DecorView.
至此,Activity&Window&ViewRootImpl的关系分析结束。
四、Dialog
在Dialog的创建过程中,也与Activity相似的创建PhoneWindow、ViewRootImp流程。例如,一般自定义Dialog的的操作如下:
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.bc_dialog_layout);
dialog.show();
其中主要来分析Dialog构造函数和Dialog.setContent()、Dialog.show()方法,在构造函数中创建了PhoneWindow,在Dialog.setContent()方法中创建了DecorView、在Dialog.show()方法中创建了ViewRootImp:
public class Dialog{
private Activity mOwnerActivity;
private final WindowManager mWindowManager;
final Context mContext;
final Window mWindow;
View mDecor;
Dialog(Context context, int themeResId, boolean createContextThemeWrapper) {
// 获取WindowManager
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
// 创建PhoneWindow
final Window w = new PhoneWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setOnWindowDismissedCallback(this);
w.setOnWindowSwipeDismissedCallback(() -> {
if (mCancelable) {
cancel();
}
});
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mListenersHandler = new android.app.Dialog.ListenersHandler(this);
}
public void setContentView(int layoutResID) {
mWindow.setContentView(layoutResID);
}
public void show() {
if (mShowing) {
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
}
onStart();
mDecor = mWindow.getDecorView();
WindowManager.LayoutParams l = mWindow.getAttributes();
// addView流程与上面分析的类似,里面创建了ViewRootImpl
mWindowManager.addView(mDecor, l);
mShowing = true;
sendShowMessage();
}
}
五、抽象的Window
Window本身是一个抽象的概念,例如按照以下方式也可以显示一个View,这个过程并没有真正创建PhoneWindow,但是把自定义view所在抽象window的parentWindow设置为了Activity的Window。
// window内要展示的view
View view = LayoutInflater.from(this).inflate(R.layout.layout_bc_window, null);
int flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
// window的参数
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, flags,
PixelFormat.TRANSPARENT);
layoutParams.gravity = Gravity.CENTER;
layoutParams.x = 0;
layoutParams.y = 0;
// 获取WindowManager
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
// WindowManager添加自定义view及windowLayoutParams;
// 方法内会创建一个decorView、ViewRootImpl,然后将自定义view添加到decorView中
windowManager.addView(view, layoutParams);
The End
欢迎关注我,一起解锁更多技能:BC的掘金主页~💐 BC的CSDN主页~💐💐
在线查看Android源码:cs.android.com/
Android源码下载:source.android.google.cn/setup/downl…
Anroid studio内源码查看方法:github.com/anggrayudi/…