当前位置: 首页 > news >正文

Android 关于设备定屏/黑屏/冻屏/ANR那些事

定屏/黑屏常见问题

我的理解是冻屏和定屏是一个意思.
冻屏:目的就是防止执行默写操作的过程出现黑屏,冻屏的过程只是不接收输入和不执行动画,并且会截取屏幕进行显示.

A:系统问题(底层/framework层)
A_1:system_server_watchdog :现象多为卡顿/黑屏

A_2:WMS(WindowManagerService)异常

A_3:surfacefling卡死,表现为定屏(冻屏)

B:app类

B_1: app ANR , 现象多为定屏/黑屏

B_2: app mainThread 阻塞, 没有触发ANR , 现象多为定屏/黑屏

C:SystemUI

C_1:systemUI ANR, 现象为定屏,按power键卡顿

[黑屏定屏那些事 - 系统机制,分析套路和实战(系统篇)](https://blog.csdn.net/feelabclihu/article/details/123911477)
//Android T
stopFreezingScreen(..)解除冻屏
startFreezingScreen(..)执行冻屏
./frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java/** Freeze the screen during a user-switch event. Called by UserController. *///WMS暴露了一个可以通过binder调用执行的冻屏操作.@Overridepublic void startFreezingScreen(int exitAnim, int enterAnim) {if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,"startFreezingScreen()")) {throw new SecurityException("Requires FREEZE_SCREEN permission");}synchronized (mGlobalLock) {if (!mClientFreezingScreen) {mClientFreezingScreen = true;//mClientFreezingScreen变量代表通过客户端进行冻结屏幕final long origId = Binder.clearCallingIdentity();try {startFreezingDisplay(exitAnim, enterAnim);//CLIENT_FREEZE_TIMEOUT超时的消息,用于结束冻结屏幕,因为客户端不可控,如果冻屏超时,系统会直接解除冻屏mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);} finally {Binder.restoreCallingIdentity(origId);}}}}private void doStartFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent,int overrideOriginalRotation) {...//获取一个WEAK LOCK防止睡眠mScreenFrozenLock.acquire();//应用启动电源模式以减少屏幕冻结时间mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);...//冻结input输入mInputManagerCallback.freezeInputDispatchingLw();...}

Android R :横竖屏切换时更新方向,执行冻屏,截图显示以及计算更新基于新的方向的DisplayInfo和Configuration.

Activity::setRequestedOrientation
->ActivityTaskManagerService::setRequestedOrientation->ActivityRecord::setRequestedOrientation->WindowContainer::setOrientation->WindowContainer::onDescendantOrientationChanged->DisplayContent::onDescendantOrientationChanged->DisplayContent::updateOrientation->DisplayRotation::updateOrientation->DisplayRotation::updateRotationUnchecked->DisplayRotation::prepareNormalRotationAnimation->WindowManagerService::startFreezingDisplay->ScreenRotationAnimation::ScreenRotationAnimation->ScreenRotationAnimation::setRotation->RotationAnimationUtils::createRotationMatrix->DisplayContent::updateDisplayAndOrientation

WMS->stopFreezingScreen()冻屏总结
WindowManagerService一个解决界面闪屏的例子
Android系统冻屏、黑屏问题的分析思路
黑屏定屏那些事 - 系统机制,分析套路和实战(系统篇)

定屏/应用卡死问题日志抓取

设备遇到应用卡死并且已经崩溃或者无响应弹框时,查看目录/data/anr/是否有日志生成.
如果目录下没有生成anr日志,界面假死:

adb shell 
su
ps -A | grep com.android.launcher3 查看当前app进程id
debuggerd -b 进程id > /sdcard/log_anr.log  打印出包含该进程的所有线程的调用栈信息

定屏死机问题抓取 Log

Android 开机动画结束后,不显示FallBackHome,(冻屏)几秒后显示Launcher3

冻屏不是黑屏,屏幕看起来像是灰的.

问题:fallbackhome Activity因configChange(uiMode、density、locale变化)频繁启动导致冻屏
解决方案:在AndroidManifest.xml中为fallbackhome配置忽略这些configChanges,以避免影响生命周期

Surface(SurfaceSyncer)同步问题分析

bug:某应用打开后,在点击home键出现黑屏
现象分析:桌面的状态时黑屏的,但是SystemUI的statusBar是显示和功能都是正常的,那一般就是当前app的问题了.

抓日志分析,发现报错: E SurfaceSyncer: Failed to find sync for id=0

黑屏原因:ViewRootImpl.java和SurfaceView 通过SurfaceSyncer产生联系,实现同步更新.
假设同步出现问题,其它流程是正常提交给wms处理,那么Surface没有同步更新会导致图形无法渲染绘制出来,那就黑屏.

Surface同步机制为android13新增,代码位置./frameworks/base/core/java/android/window/SurfaceSyncer.java,
简介:./frameworks/base/core/java/android/window/SurfaceSyncer.md.

主要作用为提供ViewRootImpl与SurfaceView(假如窗口存在SurfaceView的情况下)同步服务,实现在主Surface与SurfaceView均完成绘制时,
再去上报至WMS进行窗口状态的切换,避免主Surface绘制完成上报至WMS后、同时SurfaceView迟迟没有绘制完成使得startingWindow过早移除从而产生黑屏的现象.
Android14上保留了Surface同步机制,但是相关代码位置发生变化,不再有SurfaceSyncer.java,
而是移动至SurfaceSyncGroup.java。相关核心方法为createSyncIfNeeded、checkIfSyncIsComplete等。

[093]SurfaceSyncer的致命缺陷
参考:探索Surface同步机制
小二哥

关于Android卡顿掉帧问题

Android卡顿掉帧问题分析之实战篇

Anroid study ANR / NE(Native exception)

step 1:get events log

adb logcat -b events > e:/log.logI am_anr  : [0,770,com.android.systemui,818462221,executing service com.android.systemui/.wallpapers.ImageWallpaper]分析:
UserId=0,PID=770,包名=com.android.systemui,flags=...,anr原因:executing service com.android.systemui/.wallpapers.ImageWallpaper

step 2:查看trace文件

上面log打印了ANR的基本信息,具体ANR怎么生成的需要看trace文件,分析代码堆栈调用情况

//main(线程名)、prio(线程优先级,默认是5)、tid(线程唯一标识ID)、Sleeping/Runnable(线程当前状态)
"main" prio=5 tid=1 Runnable| group="main" sCount=0 ucsCount=0 flags=0 obj=0x722aca68 self=0xb40000764a921be0| sysTid=943 nice=0 cgrp=default sched=0/0 handle=0x77917e74f8| state=R schedstat=( 1265523861 1725170986 10361 ) utm=51 stm=75 core=3 HZ=100| stack=0x7ff7673000-0x7ff7675000 stackSize=8188KB| held mutexes= "mutator lock"(shared held)//java 堆栈调用信息(这里可查看导致ANR的代码调用流程)(分析ANR最重要的信息)at com.android.systemui.util.sensors.ThresholdSensorImpl_Builder_Factory.get(ThresholdSensorImpl_Builder_Factory.java:24)at com.android.systemui.util.sensors.SensorModule_ProvidePrimaryProximitySensorFactory.get(SensorModule_ProvidePrimaryProximitySensorFactory.java:10)at com.android.systemui.util.sensors.ProximitySensorImpl_Factory.get(ProximitySensorImpl_Factory.java:123)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0e98eb91> (a dagger.internal.DoubleCheck) // 锁住对象0x0e98eb91at com.android.systemui.privacy.PrivacyConfig_Factory.get(PrivacyConfig_Factory.java:135)at com.android.systemui.classifier.FalsingCollectorImpl_Factory.get(FalsingCollectorImpl_Factory.java:38)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0208aaf6> (a dagger.internal.DoubleCheck)at com.android.systemui.keyguard.dagger.KeyguardModule_NewKeyguardViewMediatorFactory.get(KeyguardModule_NewKeyguardViewMediatorFactory.java:23)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x020beef7> (a dagger.internal.DoubleCheck)at dagger.internal.DelegateFactory.get(DelegateFactory.java:4)at com.android.systemui.unfold.UnfoldSharedModule_UnfoldKeyguardVisibilityProviderFactory.get(UnfoldSharedModule_UnfoldKeyguardVisibilityProviderFactory.java:49)at com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager_Factory.get(StatusBarKeyguardViewManager_Factory.java:12)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0bee3164> (a dagger.internal.DoubleCheck)at dagger.internal.DelegateFactory.get(DelegateFactory.java:4)at com.android.systemui.keyguard.KeyguardUnlockAnimationController_Factory.get(KeyguardUnlockAnimationController_Factory.java:32)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0ecfafcd> (a dagger.internal.DoubleCheck)at dagger.internal.DelegateFactory.get(DelegateFactory.java:4)at com.android.systemui.statusbar.phone.ScrimController_Factory.get(ScrimController_Factory.java:103)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0b8c8082> (a dagger.internal.DoubleCheck)at com.android.systemui.statusbar.phone.DozeServiceHost_Factory.get(DozeServiceHost_Factory.java:67)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x00868393> (a dagger.internal.DoubleCheck)at com.android.systemui.keyguard.data.repository.KeyguardRepositoryImpl_Factory.get(KeyguardRepositoryImpl_Factory.java:17)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0c0effd0> (a dagger.internal.DoubleCheck)at com.android.systemui.keyguard.domain.interactor.KeyguardInteractor_Factory.get(KeyguardInteractor_Factory.java:2)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0f347bc9> (a dagger.internal.DoubleCheck)at com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor_Factory.get(KeyguardQuickAffordanceInteractor_Factory.java:2)at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)- locked <0x0d8622ce> (a dagger.internal.DoubleCheck)at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$ReferenceSysUIComponentImpl.injectCustomizationProvider(DaggerReferenceGlobalRootComponent.java:2)at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$ReferenceSysUIComponentImpl.inject(DaggerReferenceGlobalRootComponent.java:4)at java.lang.reflect.Method.invoke(Native method)at com.android.systemui.SystemUIAppComponentFactoryBase$instantiateProviderCompat$1.onContextAvailable(SystemUIAppComponentFactoryBase.kt:42)at com.android.systemui.keyguard.CustomizationProvider.attachInfo(CustomizationProvider.kt:7)at android.app.ActivityThread.installProvider(ActivityThread.java:7514)at android.app.ActivityThread.installContentProviders(ActivityThread.java:7025)at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6796)at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2133)at android.os.Handler.dispatchMessage(Handler.java:106)at android.os.Looper.loopOnce(Looper.java:201)at android.os.Looper.loop(Looper.java:288)at android.app.ActivityThread.main(ActivityThread.java:7924)at java.lang.reflect.Method.invoke(Native method)at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

补丁:
Traces中显示的线程状态都是C代码定义的,通过查看线程状态对应的信息分析ANR问题
TimedWaiting对应的线程状态是TIMED_WAITING;

kTimedWaiting, // TIMED_WAITING TS_WAIT in Object.wait() with a timeout 执行了无超时参数的wait函数
kSleeping, // TIMED_WAITING TS_SLEEPING in Thread.sleep() 执行了带有超时参数的sleep函数ZOMBIE                              线程死亡,终止运行
RUNNING/RUNNABLE                    线程可运行或正在运行
TIMED_WAIT                          执行了带有超时参数的wait、sleep或join函数
MONITOR                             线程阻塞,等待获取对象锁
WAIT                                执行了无超时参数的wait函数
INITIALIZING                        新建,正在初始化,为其分配资源
STARTING                            新建,正在启动
NATIVE                              正在执行JNI本地函数
VMWAIT                              正在等待VM资源
SUSPENDED                           线程暂停,通常是由于GC或debug被暂停

Android中ANR的分析和解决
Android内存异常机制(用户空间)_NE
trace详解
Android ANR分析-笔记
Android ANR基本Log分析
Android ANR traces.txt文件分析
Android ANR 2

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【北京仁爱堂】脖子歪斜,拉扯疼痛怎么办?规律的生活让痉挛性斜颈的恢复事半功倍!
  • 微信小程序登陆
  • 【精选】基于springboot个人理财APP(源码+设计+辅导)
  • MATLAB 低版本Matlab-读取LAS格式点云文件并可视化(78)
  • C++ 设计模式——迭代器模式
  • 令牌和签名详细介绍+开发使用教程
  • 聚星文社下载地址
  • 光性能 -- OSNR,BER与Q值
  • Nginx 405 not allowed
  • WPS宏实现Sheet页合并功能
  • 区间预测|基于灰狼优化最小二乘支持向量机的多变量回归区间预测Matlab程序GWO-LSSVM-ABKDE
  • 做项目过程中问题小汇总 | vue3 elementplus js
  • DDoS攻击导致服务器宕机的技术解析
  • PXE-Kickstart高效批量装机
  • 32 - III. 从上到下打印二叉树 III
  • 2018一半小结一波
  • Java Agent 学习笔记
  • Java多态
  • mysql 5.6 原生Online DDL解析
  • Spark学习笔记之相关记录
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 测试如何在敏捷团队中工作?
  • 创建一种深思熟虑的文化
  • 对JS继承的一点思考
  • 关于extract.autodesk.io的一些说明
  • 坑!为什么View.startAnimation不起作用?
  • 数组的操作
  • 移动端 h5开发相关内容总结(三)
  • 用Canvas画一棵二叉树
  • 积累各种好的链接
  • ​LeetCode解法汇总518. 零钱兑换 II
  • #100天计划# 2013年9月29日
  • #预处理和函数的对比以及条件编译
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (3)医疗图像处理:MRI磁共振成像-快速采集--(杨正汉)
  • (Forward) Music Player: From UI Proposal to Code
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .a文件和.so文件
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .gitignore文件---让git自动忽略指定文件
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET Micro Framework 4.2 beta 源码探析
  • .net 获取某一天 在当月是 第几周 函数
  • .Net8 Blazor 尝鲜
  • .net项目IIS、VS 附加进程调试
  • @Async 异步注解使用
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • [Asp.net MVC]Asp.net MVC5系列——Razor语法