主要观点总结
文章主要讨论了在排查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
………………………………