- 浏览: 22408 次
- 性别:
- 来自: 北京
最新评论
page7
在这篇文章里, 我们分析一下W类的构造过程. W类是定义在ViewRootImpl类中的一个内部类, W类的定义如下:
static class W extends IWindow.Stub
由此可见, W本质上是一个Binder本地对象, 其实这是会传给WindowManagerService的, WindowManagerService就是通过W来通知Activity对象执行一些操作.
W的构造函数如下:
W(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
mWindowSession = viewAncestor.mWindowSession;
}
由此可见, W拿着ViewRootImpl和WindowSession.
page8
我们分析一下ViewRootImpl的setView函数的实现:
1 public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
2 synchronized (this) {
3 if (mView == null) {
4 mView = view;
5 mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
6 mFallbackEventHandler.setView(view);
7 mWindowAttributes.copyFrom(attrs);
8 attrs = mWindowAttributes;
9 // Keep track of the actual window flags supplied by the client.
10 mClientWindowLayoutFlags = attrs.flags;
11
12 setAccessibilityFocus(null, null);
13
14 if (view instanceof RootViewSurfaceTaker) {
15 mSurfaceHolderCallback =
16 ((RootViewSurfaceTaker)view).willYouTakeTheSurface();
17 if (mSurfaceHolderCallback != null) {
18 mSurfaceHolder = new TakenSurfaceHolder();
19 mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
20 }
21 }
22
23 CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
24 mTranslator = compatibilityInfo.getTranslator();
25
26 // If the application owns the surface, don't enable hardware acceleration
27 if (mSurfaceHolder == null) {
28 enableHardwareAcceleration(mView.getContext(), attrs);
29 }
30
31 boolean restore = false;
32 if (mTranslator != null) {
33 mSurface.setCompatibilityTranslator(mTranslator);
34 restore = true;
35 attrs.backup();
36 mTranslator.translateWindowLayout(attrs);
37 }
38 if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
39
40 if (!compatibilityInfo.supportsScreen()) {
41 attrs.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
42 mLastInCompatMode = true;
43 }
44
45 mSoftInputMode = attrs.softInputMode;
46 mWindowAttributesChanged = true;
47 mWindowAttributesChangesFlag = WindowManager.LayoutParams.EVERYTHING_CHANGED;
48 mAttachInfo.mRootView = view;
49 mAttachInfo.mScalingRequired = mTranslator != null;
50 mAttachInfo.mApplicationScale =
51 mTranslator == null ? 1.0f : mTranslator.applicationScale;
52 if (panelParentView != null) {
53 mAttachInfo.mPanelParentWindowToken
54 = panelParentView.getApplicationWindowToken();
55 }
56 mAdded = true;
57 int res; /* = WindowManagerImpl.ADD_OKAY; */
58
59 // Schedule the first layout -before- adding to the window
60 // manager, to make sure we do the relayout before receiving
61 // any other events from the system.
62 requestLayout();
63 if ((mWindowAttributes.inputFeatures
64 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
65 mInputChannel = new InputChannel();
66 }
67 try {
68 mOrigWindowType = mWindowAttributes.type;
69 mAttachInfo.mRecomputeGlobalAttributes = true;
70 collectViewAttributes();
71 res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
72 getHostVisibility(), mDisplay.getDisplayId(),
73 mAttachInfo.mContentInsets, mInputChannel);
74 } catch (RemoteException e) {
75 mAdded = false;
76 mView = null;
77 mAttachInfo.mRootView = null;
78 mInputChannel = null;
79 mFallbackEventHandler.setView(null);
80 unscheduleTraversals();
81 setAccessibilityFocus(null, null);
82 throw new RuntimeException("Adding window failed", e);
83 } finally {
84 if (restore) {
85 attrs.restore();
86 }
87 }
88
89 if (mTranslator != null) {
90 mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
91 }
92 mPendingContentInsets.set(mAttachInfo.mContentInsets);
93 mPendingVisibleInsets.set(0, 0, 0, 0);
94 if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow);
95 if (res < WindowManagerGlobal.ADD_OKAY) {
96 mAttachInfo.mRootView = null;
97 mAdded = false;
98 mFallbackEventHandler.setView(null);
99 unscheduleTraversals();
100 setAccessibilityFocus(null, null);
101 switch (res) {
102 case WindowManagerGlobal.ADD_BAD_APP_TOKEN:
103 case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:
104 throw new WindowManager.BadTokenException(
105 "Unable to add window -- token " + attrs.token
106 + " is not valid; is your activity running?");
107 case WindowManagerGlobal.ADD_NOT_APP_TOKEN:
108 throw new WindowManager.BadTokenException(
109 "Unable to add window -- token " + attrs.token
110 + " is not for an application");
111 case WindowManagerGlobal.ADD_APP_EXITING:
112 throw new WindowManager.BadTokenException(
113 "Unable to add window -- app for token " + attrs.token
114 + " is exiting");
115 case WindowManagerGlobal.ADD_DUPLICATE_ADD:
116 throw new WindowManager.BadTokenException(
117 "Unable to add window -- window " + mWindow
118 + " has already been added");
119 case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED:
120 // Silently ignore -- we would have just removed it
121 // right away, anyway.
122 return;
123 case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON:
124 throw new WindowManager.BadTokenException(
125 "Unable to add window " + mWindow +
126 " -- another window of this type already exists");
127 case WindowManagerGlobal.ADD_PERMISSION_DENIED:
128 throw new WindowManager.BadTokenException(
129 "Unable to add window " + mWindow +
130 " -- permission denied for this window type");
131 case WindowManagerGlobal.ADD_INVALID_DISPLAY:
132 throw new WindowManager.InvalidDisplayException(
133 "Unable to add window " + mWindow +
134 " -- the specified display can not be found");
135 }
136 throw new RuntimeException(
137 "Unable to add window -- unknown error code " + res);
138 }
139
140 if (view instanceof RootViewSurfaceTaker) {
141 mInputQueueCallback =
142 ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
143 }
144 if (mInputChannel != null) {
145 if (mInputQueueCallback != null) {
146 mInputQueue = new InputQueue(mInputChannel);
147 mInputQueueCallback.onInputQueueCreated(mInputQueue);
148 } else {
149 mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
150 Looper.myLooper());
151 }
152 }
153
154 view.assignParent(this);
155 mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0;
156 mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0;
157
158 if (mAccessibilityManager.isEnabled()) {
159 mAccessibilityInteractionConnectionManager.ensureConnection();
160 }
161
162 if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
163 view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
164 }
165 }
166 }
167 }
168
第2行(ViewRootImpl->setView)会加锁
第3行(ViewRootImpl->setView)会保证一个ViewRootImpl只对应一个View
第4行(ViewRootImpl->setView)将成员变量mView设置成DecorView
第62行(ViewRootImpl->setView)会调用requestLayout()函数来进行一次layout, 而这是在加入到WindowManagerService管理之前进行的, 关于这部分的分析可以参考View的刷新部分的分析.
第71-73行(ViewRootImpl->setView)会调用WindowSession的addToDisplay函数将mWindow传给WindowManagerService, 关于这部分的分析可以参考Activity和WindowManagerService连接系列的文章.
page9
我们来看一下PhoneWidnow的getDecorView函数的实现:
public final View getDecorView() {
if (mDecor == null) {
installDecor();
}
return mDecor;
}
getDecorView函数如果发现mDecor还没有初始化过, 就会调用installDecor函数来构造一个DecorView
在这篇文章里, 我们分析一下W类的构造过程. W类是定义在ViewRootImpl类中的一个内部类, W类的定义如下:
static class W extends IWindow.Stub
由此可见, W本质上是一个Binder本地对象, 其实这是会传给WindowManagerService的, WindowManagerService就是通过W来通知Activity对象执行一些操作.
W的构造函数如下:
W(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
mWindowSession = viewAncestor.mWindowSession;
}
由此可见, W拿着ViewRootImpl和WindowSession.
page8
我们分析一下ViewRootImpl的setView函数的实现:
1 public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
2 synchronized (this) {
3 if (mView == null) {
4 mView = view;
5 mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
6 mFallbackEventHandler.setView(view);
7 mWindowAttributes.copyFrom(attrs);
8 attrs = mWindowAttributes;
9 // Keep track of the actual window flags supplied by the client.
10 mClientWindowLayoutFlags = attrs.flags;
11
12 setAccessibilityFocus(null, null);
13
14 if (view instanceof RootViewSurfaceTaker) {
15 mSurfaceHolderCallback =
16 ((RootViewSurfaceTaker)view).willYouTakeTheSurface();
17 if (mSurfaceHolderCallback != null) {
18 mSurfaceHolder = new TakenSurfaceHolder();
19 mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
20 }
21 }
22
23 CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
24 mTranslator = compatibilityInfo.getTranslator();
25
26 // If the application owns the surface, don't enable hardware acceleration
27 if (mSurfaceHolder == null) {
28 enableHardwareAcceleration(mView.getContext(), attrs);
29 }
30
31 boolean restore = false;
32 if (mTranslator != null) {
33 mSurface.setCompatibilityTranslator(mTranslator);
34 restore = true;
35 attrs.backup();
36 mTranslator.translateWindowLayout(attrs);
37 }
38 if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
39
40 if (!compatibilityInfo.supportsScreen()) {
41 attrs.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
42 mLastInCompatMode = true;
43 }
44
45 mSoftInputMode = attrs.softInputMode;
46 mWindowAttributesChanged = true;
47 mWindowAttributesChangesFlag = WindowManager.LayoutParams.EVERYTHING_CHANGED;
48 mAttachInfo.mRootView = view;
49 mAttachInfo.mScalingRequired = mTranslator != null;
50 mAttachInfo.mApplicationScale =
51 mTranslator == null ? 1.0f : mTranslator.applicationScale;
52 if (panelParentView != null) {
53 mAttachInfo.mPanelParentWindowToken
54 = panelParentView.getApplicationWindowToken();
55 }
56 mAdded = true;
57 int res; /* = WindowManagerImpl.ADD_OKAY; */
58
59 // Schedule the first layout -before- adding to the window
60 // manager, to make sure we do the relayout before receiving
61 // any other events from the system.
62 requestLayout();
63 if ((mWindowAttributes.inputFeatures
64 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
65 mInputChannel = new InputChannel();
66 }
67 try {
68 mOrigWindowType = mWindowAttributes.type;
69 mAttachInfo.mRecomputeGlobalAttributes = true;
70 collectViewAttributes();
71 res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
72 getHostVisibility(), mDisplay.getDisplayId(),
73 mAttachInfo.mContentInsets, mInputChannel);
74 } catch (RemoteException e) {
75 mAdded = false;
76 mView = null;
77 mAttachInfo.mRootView = null;
78 mInputChannel = null;
79 mFallbackEventHandler.setView(null);
80 unscheduleTraversals();
81 setAccessibilityFocus(null, null);
82 throw new RuntimeException("Adding window failed", e);
83 } finally {
84 if (restore) {
85 attrs.restore();
86 }
87 }
88
89 if (mTranslator != null) {
90 mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
91 }
92 mPendingContentInsets.set(mAttachInfo.mContentInsets);
93 mPendingVisibleInsets.set(0, 0, 0, 0);
94 if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow);
95 if (res < WindowManagerGlobal.ADD_OKAY) {
96 mAttachInfo.mRootView = null;
97 mAdded = false;
98 mFallbackEventHandler.setView(null);
99 unscheduleTraversals();
100 setAccessibilityFocus(null, null);
101 switch (res) {
102 case WindowManagerGlobal.ADD_BAD_APP_TOKEN:
103 case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:
104 throw new WindowManager.BadTokenException(
105 "Unable to add window -- token " + attrs.token
106 + " is not valid; is your activity running?");
107 case WindowManagerGlobal.ADD_NOT_APP_TOKEN:
108 throw new WindowManager.BadTokenException(
109 "Unable to add window -- token " + attrs.token
110 + " is not for an application");
111 case WindowManagerGlobal.ADD_APP_EXITING:
112 throw new WindowManager.BadTokenException(
113 "Unable to add window -- app for token " + attrs.token
114 + " is exiting");
115 case WindowManagerGlobal.ADD_DUPLICATE_ADD:
116 throw new WindowManager.BadTokenException(
117 "Unable to add window -- window " + mWindow
118 + " has already been added");
119 case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED:
120 // Silently ignore -- we would have just removed it
121 // right away, anyway.
122 return;
123 case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON:
124 throw new WindowManager.BadTokenException(
125 "Unable to add window " + mWindow +
126 " -- another window of this type already exists");
127 case WindowManagerGlobal.ADD_PERMISSION_DENIED:
128 throw new WindowManager.BadTokenException(
129 "Unable to add window " + mWindow +
130 " -- permission denied for this window type");
131 case WindowManagerGlobal.ADD_INVALID_DISPLAY:
132 throw new WindowManager.InvalidDisplayException(
133 "Unable to add window " + mWindow +
134 " -- the specified display can not be found");
135 }
136 throw new RuntimeException(
137 "Unable to add window -- unknown error code " + res);
138 }
139
140 if (view instanceof RootViewSurfaceTaker) {
141 mInputQueueCallback =
142 ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
143 }
144 if (mInputChannel != null) {
145 if (mInputQueueCallback != null) {
146 mInputQueue = new InputQueue(mInputChannel);
147 mInputQueueCallback.onInputQueueCreated(mInputQueue);
148 } else {
149 mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
150 Looper.myLooper());
151 }
152 }
153
154 view.assignParent(this);
155 mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0;
156 mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0;
157
158 if (mAccessibilityManager.isEnabled()) {
159 mAccessibilityInteractionConnectionManager.ensureConnection();
160 }
161
162 if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
163 view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
164 }
165 }
166 }
167 }
168
第2行(ViewRootImpl->setView)会加锁
第3行(ViewRootImpl->setView)会保证一个ViewRootImpl只对应一个View
第4行(ViewRootImpl->setView)将成员变量mView设置成DecorView
第62行(ViewRootImpl->setView)会调用requestLayout()函数来进行一次layout, 而这是在加入到WindowManagerService管理之前进行的, 关于这部分的分析可以参考View的刷新部分的分析.
第71-73行(ViewRootImpl->setView)会调用WindowSession的addToDisplay函数将mWindow传给WindowManagerService, 关于这部分的分析可以参考Activity和WindowManagerService连接系列的文章.
page9
我们来看一下PhoneWidnow的getDecorView函数的实现:
public final View getDecorView() {
if (mDecor == null) {
installDecor();
}
return mDecor;
}
getDecorView函数如果发现mDecor还没有初始化过, 就会调用installDecor函数来构造一个DecorView
发表评论
-
Activity与WindowManagerService连接的过程(三)
2018-04-16 16:27 582page11 WindowManagerService ... -
Activity与WindowManagerService连接的过程(二)
2018-04-16 16:36 697page6 WindowManagerGlobal的getW ... -
Activity与WindowManagerService连接的过程(一)
2018-04-16 16:21 952page1 Activity组件在 ... -
Activity的ViewRoot的创建过程(二)
2017-11-06 14:29 865page4 我们看一下ViewRootImpl对象的创 ... -
Activity的ViewRoot的创建过程(一)
2017-11-06 14:27 1021page1 当一个Activity第一次激活的时候会为该Ac ... -
Activity的Window和WindowManager的创建过程(三)
2017-07-05 11:49 1292page9 在这里我们分析一下DisplayManager的 ... -
Activity的Window和WindowManager的创建过程(二)
2017-07-05 11:31 497page5 在这篇文章中, 我们分析一下ContextImp ... -
Activity的Window和WindowManager的创建过程(一)
2017-07-05 11:27 571page1 我们开始分析一下Activity的Window和 ... -
Acitivy创建Context的过程(二)
2017-06-21 14:11 440page4 在这里我们分析一下ContextImpl的ini ... -
Acitivy创建Context的过程(一)
2017-06-21 14:15 578page1 从本篇文章开始,我们分析一下Activity创建 ... -
应用程序进程与SurfaceFlinger的连接过程
2017-06-21 11:49 1022我们从SurfaceComposerClient对象的创建开始 ... -
Android源码之SurfaceFlinger的启动(三)
2017-04-20 11:09 1001page11 我们来看一下SurfaceFlinger ... -
Android源码之SurfaceFlinger的启动(二)
2017-04-18 15:15 811page6 我们看一下Thread的run函数的实现: ... -
Android源码之SurfaceFlinger的启动(一)
2017-04-17 10:07 905page1 在Android系统中, 显示系统在底层是通过S ... -
Android源码之Zygote
2015-12-15 11:45 480当ActivityManagerService启动一个应用程序 ... -
Android源码之Binder(五)
2015-12-04 09:19 1410Service组件在启动时,需要将自己注册到Service M ... -
Android源码之Binder(四)
2015-12-04 09:18 1796case BINDER_SET_MAX_THREADS: ... -
Android源码之Binder(三)
2015-12-04 09:17 878{ int ret; struct binder_pr ... -
Android源码之Binder(二)
2015-12-04 09:15 502分析完Binder驱动程序的打开和内存分配的过程之后,我们看一 ... -
Android源码之Binder(一)
2015-12-04 09:12 959在Android系统中,进程间通信使用的是Binder机制。B ...
相关推荐
主要包括activity、view 以及布局三大部分,其中包含activity之间的数据传递
关于Android Studio升级为V4.1.1Activity不能创建解决方法
掌握Activity的创建过程和配置。理解Activity的生命周期以及各个生命周期方法的使用。掌握页面切换的两种方法。 【实践要求】 1.理解Activity的组成结构和创建过程; 2.了解Activity的生命周期; 3.掌握Activity页面...
反射获取顶层activity实例
activity view window viewgroup的关系
activity-oracle建表SQLactivity-oracle建表SQLactivity-oracle建表SQL
有几个情况下 Activity 会...者是 Activity 通过调用 finish()发出了停止信号。系统也有可能会在 Activity 处于 stop 状态且长时间不被使用、或在前台 Activity 需要更多系统资源的时候关闭后台进程以获取 更多的内存。
要分析Activity中的Window的创建过程就必须了解Activity的启动过程,详细的启动过程参考Activity的启动过程 。 Activity的启动过程很复杂, 最终会由ActivityThread中的performLaunchActivity()方法来完成整个启动...
多activity的创建及其交互 demo
Activity2.1:创建并使用COM+服务组件 Creating and Using a COM+ Serviced Component
LocalActivityManager类是管理activity的,然后通过startActivity(String id, Intent intent)这个方法获取Window获取当前Window对象,再然后调用getDecorView()方法获取当前activity对应的view,这样就可以使用...
Activity和Service是应用程序的核心组件,程序框架层提供了一套完整的机制来协助应用程序启动Activity和Service
Android开发中activity的工作过程xmind,便于学习Android中activity。
轻松实现进入Activity或者Fragment的时候为view创建漂亮的过渡效果.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
Activity启动过程
Activity启动时候获取View宽高的四种方法,因为Activity的生命周期回调和view的measure过程不是同步执行的,所以无法在activity的onCreate、onStart和onResume里面准确的获取view的宽和高,可以通过以下四个方法来...
Activity6.0 默认不支持达梦数据库,需要进行适配,本文详细讲解了适配的过程
activity3activity3
如果在任务的栈顶正好存在该Activity的实例,就重用该实例,并且会调用实例的OnNewIntent()方法,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。 3.singleTask ...
Activity 启动过程源码+分析过程