什么网站可以做设计赚钱吗,南京十大软件公司排名,武安建设局网站,gps定位网站建设一. 基础知识介绍 1. WakeLock#xff08;休眠锁#xff09; WakeLock用于保持设备的唤醒状态#xff0c;有些情况下#xff0c;即时用户不操作App#xff0c;我们也需要保持屏幕处于唤醒状态#xff0c;以保证用户体验#xff0c;比如视频类APP和计步类APP#xff0c;…一. 基础知识介绍 1. WakeLock休眠锁 WakeLock用于保持设备的唤醒状态有些情况下即时用户不操作App我们也需要保持屏幕处于唤醒状态以保证用户体验比如视频类APP和计步类APP视频类APP需要屏幕一直保持常量计步类APP要求熄屏后程序依然保持运行状态。 2. WakeLock的多种类型 PARTIAL_WAKE_LOCK:保持CPU正常运转但屏幕和键盘灯都可能是关闭的。SCREEN_DIM_WAKE_LOCK:保持CPU正常运转允许屏幕点亮但可能屏幕被置灰键盘灯可能是关闭的。SCREEN_BRIGHT_WAKE_LOCK:保持CPU正常运转允许屏幕高亮显示键盘灯可能是关闭的。FULL_WAKE_LOCK:保持CPU正常运转保持屏幕高亮显示键盘灯也保持亮度。ACQUIRE_CAUSES_WAKEUP:强制屏幕和键盘灯亮起这种锁针对一些必须通知用户的操作。ON_AFTER_RELEASE:当WakeLock被释放后继续保持屏幕和键盘灯亮起一段时间。 二. 遇到不灭屏的解决方法
1. 方法一 使用adb shell dumpsys dumpsys.txt 或者在bugreport.zip 或者使用命令: adb shell dumpsys power power_dump.txt 搜索关键字:Wake Locks: 查看对应的持有对象。 实例分析:
1. 案例一 复现场景: [settings]settings-display-screen timeout-设置15秒15秒后手机不灭屏.(低概率) (1) 查看dump power的信息: Wake Locks: size1 FULL_WAKE_LOCK TinnoFactory ACQUIRE_CAUSES_WAKEUP ACQ-55m1s400ms (uid1000 pid16340) (2) 发现有持有TinnoFactory TAG的 wake lock (FULL_WAKE_LOCK)导致不能灭屏。
(3) 查看代码: private static final String TAG TinnoFactory; /** Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, TinnoFactoryActivity onCreate); PowerManager pm (PowerManager) getSystemService(POWER_SERVICE); wakeLock pm.newWakeLock(PowerManager.FULL_WAKE_LOCK| PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG); wakeLock.acquire(); Override public void onDestroy() { Log.d(TAG, TinnoFactoryActivity onDestroy); // Log.i(TAG, onDestroy, reset previousMobileDataState); // setMobileDataState(mPreviousMobileDataState); // Log.i(TAG, setMobileData, getMobileDataState getMobileDataState()); if (wakeLock ! null) {wakeLock.release();} super.onDestroy(); } (4) 这个应用退出来就可以恢复。
2. 案例二 复现场景: 将timeout 时间设置为15秒。在打电话界面停留超过15秒手机不灭屏。 (1) 查看dump power的信息: SCREEN_BRIGHT_WAKE_LOCK WindowManager ON_AFTER_RELEASE ACQ-1m56s271ms (uid1000 pid1344 wsWorkSource{10172}) (2) 发现有持有WindowManager TAG,是来自uid: 10172, 通过日志发现10172是dialer应用。 (3) 分析WindowManager TAG怎么持有wake lock。 使用倒序的方法找: 1) TAG 定义:
TAG_WM 定义:
frameworks/base/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java public class WindowManagerDebugConfig { ... static final String TAG_WM WindowManager; .. 2) 调用newWakeLock SCREEN_BRIGHT_WAKE_LOCK的地方:
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java private WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, SupplierSurfaceControl.Transaction transactionFactory, SupplierSurface surfaceFactory, FunctionSurfaceSession, SurfaceControl.Builder surfaceControlFactory) { ... mHoldingScreenWakeLock mPowerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM); ... } 3)谁在使用mHoldingScreenWakeLock.
只要newHoldScreen不为null若调用setHoldScreenLocked则就会调用acquire函数. void setHoldScreenLocked(final Session newHoldScreen) { final boolean hold newHoldScreen ! null; ... if (hold ! state) { if (hold) { mHoldingScreenWakeLock.acquire(); mPolicy.keepScreenOnStartedLw(); } .. 4) 接下来寻找是调用setHoldScreenLocked 函数 发现只有一处是在RootWindowContainer.java 中。
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java // Something has changed! Lets make it correct now. // TODO: Super long method that should be broken down... void performSurfacePlacementNoTrace() { ... mWmService.setHoldScreenLocked(mHoldScreen); .. 5) 查看是谁给mHoldScreen赋值。
也是只有一处当设置flag是FLAG_KEEP_SCREEN_ON。
android/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java /** * param w WindowState this method is applied to. * param obscured True if there is a window on top of this obscuring the display. * param syswin System window? * return True when the display contains content to show the user. When false, the display * manager may choose to mirror or blank the display. */ boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) { if (w.mHasSurface canBeSeen) { if ((attrFlags FLAG_KEEP_SCREEN_ON) ! 0) { mHoldScreen w.mSession; mHoldScreenWindow w; } (4) 在dialer 中查看是谁使用了FLAG_KEEP_SCREEN_ON 。 果真有有相应的代码进行debug调试既可.
vendor/mediatek/proprietary/packages/apps/Dialer/java/com/android/incallui/InCallPresenter.java private void applyScreenTimeout() { if (screenTimeoutEnabled) { window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } else { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } }