专栏名称: 鸿洋
你好,欢迎关注鸿洋的公众号,每天为您推送高质量文章,让你每天都能涨知识。点击历史消息,查看所有已推送的文章,喜欢可以置顶本公众号。此外,本公众号支持投稿,如果你有原创的文章,希望通过本公众号发布,欢迎投稿。
目录
相关文章推荐
郭霖  ·  activityGuard:Android ... ·  昨天  
鸿洋  ·  Android anr排查之sp卡顿 ·  2 天前  
鸿洋  ·  再学安卓 - init进程 ·  3 天前  
今天看啥  ›  专栏  ›  鸿洋

Android anr排查之sp卡顿

鸿洋  · 公众号  · android  · 2024-12-24 08:35
    

主要观点总结

文章主要讨论了在排查ANR问题时遇到的SharedPreference卡顿问题,通过解析apply流程来发现问题并提出解决方案。

关键观点总结

关键观点1: SharedPreference的apply流程导致主线程卡顿的问题

SharedPreference的apply方法在执行时会将任务提交到QueuedWork执行,主线程会在页面退出前阻塞等待sp完成,造成block等待甚至ANR。

关键观点2: 问题解决的正向思路

简化数据存储,如果数据复杂考虑存到数据库而不是一股脑往sp写。

关键观点3: 问题解决的篡改思路

通过反射篡改SharedPreference的某些字段,避免主线程阻塞等待,降低ANR风险。具体实现包括替换sFinishers字段保证每次获取都是空列表,替换sWork字段让每次执行的时候在子线程启动。


文章预览

今天分享一下之前在排查anr的时候遇到的一个卡顿问题。因为隔得时间有点久了,所以堆栈找不到了。只能记得这个卡顿的堆栈是长时间block在 QueuedWork.waitToFinish 的调用处,业务触发点则是SharedPreference 的 apply。 SharedPreference apply不是运行在子线程吗,为什么还会导致主线程卡顿?我们从apply的流程看起: 1 问题分析 sp在commit的时候会直接在当前线程执行 commitToMemory 和 enqueueDiskWrite : // SharedPreferenceImpl.java @Override public   boolean   commit ()   {    long  startTime =  0 ;   MemoryCommitResult mcr = commitToMemory();   SharedPreferencesImpl. this .enqueueDiskWrite(mcr,  null );    try  {     mcr.writtenToDiskLatch.await();   }  catch  (InterruptedException e) {      return   false ;   }  finally  {   }   notifyListeners(mcr);    return  mcr.writeToDiskResult; } apply逻辑如下: @Override public   void   appl ………………………………

原文地址:访问原文地址
快照地址: 访问文章快照
总结与预览地址:访问总结与预览