2020-09-22
程序员文章站
2022-04-12 22:07:55
Activity KEEP_SCREEN_ON原理我们都支持如果要保持activity界面常亮,在activity的onCreate中加入如下代码即可:getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);底层的最终实现是WMS中的WakeLock实现的,变量WindowManagerService中的mHoldingScreenWakeLock。WMS的源码路径是:/frameworks/base/servic...
Activity KEEP_SCREEN_ON原理
我们都支持如果要保持activity界面常亮,在activity的onCreate中加入如下代码即可:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
底层的最终实现是WMS中的WakeLock实现的,变量WindowManagerService中的mHoldingScreenWakeLock。
WMS的源码路径是:
/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
那从addflag到mHoldingScreenWakeLock底做经历了什么,流程又是怎么样的呢?
先上图:
!
某某activity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
PhoneWindow
public void addFlags(int flags) {
setFlags(flags, flags);
}
public void setFlags(int flags, int mask) {
...
dispatchWindowAttributesChanged(attrs);
}
protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
}
Activity
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
...
getWindowManager().updateViewLayout(decor, params);
...
}
}
WindowManagerImpl
@Override
public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
...
mGlobal.updateViewLayout(view, params);
}
WindowManagerGlobal
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
...
root.setLayoutParams(wparams, false);
...
}
ViewRootImpl
void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
synchronized (this) {
...
if (newView) {
mSoftInputMode = attrs.softInputMode;
requestLayout();
}
...
scheduleTraversals();
}
}
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void scheduleTraversals() {
...
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
...
}
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void doTraversal() {
....
performTraversals();
....
}
private void performTraversals() {
...
performDraw();
...
}
private void performDraw() {
...
try {
mWindowSession.finishDrawing(mWindow);
} catch (RemoteException e) {
}
}
}
Session
@Override
public void finishDrawing(IWindow window) {
mService.finishDrawingWindow(this, window);
}
WindowManagerService
public void finishDrawingWindow(Session session, IWindow client) {
...
mWindowPlacerLocked.requestTraversal();
...
}
WindowSurfacePlacer
void requestTraversal() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mService.mH.sendEmptyMessage(DO_TRAVERSAL);
}
}
WindowManagerService
case DO_TRAVERSAL: {
synchronized(mWindowMap) {
mWindowPlacerLocked.performSurfacePlacement();
}
} break;
WindowSurfacePlacer
final void performSurfacePlacement() {
...
performSurfacePlacementLoop();
...
}
private void performSurfacePlacementLoop() {
....
performSurfacePlacementInner(recoveringMemory);
...
}
private void performSurfacePlacementInner(boolean recoveringMemory) {
...
mService.setHoldScreenLocked(mHoldScreen);
...
}
WindowManagerService
void setHoldScreenLocked(final Session newHoldScreen) {
...
mHoldingScreenWakeLock.acquire();
...
}
至此,整个KEEP_SCREEN_ON的代码执行流程完毕。
如有问题,请联系博主~欢迎指正
本文地址:https://blog.csdn.net/dadan_jiku/article/details/108734472