三星 Note 3:按下 SPen 侧键后出现 Activity Memory Leak
Posted
技术标签:
【中文标题】三星 Note 3:按下 SPen 侧键后出现 Activity Memory Leak【英文标题】:Samsung Note 3: Activity Memory Leak after pressing SPen side button 【发布时间】:2018-02-09 12:46:41 【问题描述】:在没有实现任何与 SPen 相关的 SDK 库的情况下,AppCompatActivity
扩展类会发生内存泄漏。
以下事件序列通常会触发内存泄漏:
-
用户按下侧边按钮,激活 Air Command 工具。
不点击任何空中命令工具的图标,再次点击侧边按钮。
屏幕旋转,在这种情况下会导致 Activity 被销毁并重新启动。
通过 android Studio 执行 Java 堆转储会发现被破坏的 Activity 存在内存泄漏。
分析器表明activity mContext变量被包类引用:com.samsung.android.smartclip.SpenGestureManager。这很可能会导致活动内存泄漏。
是否有任何方法可以清除对 SpenGestureManager 类持有的 mContext 变量的引用?这有望让垃圾收集器清除被破坏的活动。
在以下设备/Android 版本(Samsung Galaxy Note 3 Duos)上检测到此问题:
型号:SM-N9002 Android 版本:4.4.2 (KitKat) 基带版本:N9002ZNUFNK1 ROM版本:SVA ROM SM-N9002 v9.0在三星 Galaxy Note 10.1 设备上测试了相同的应用程序,该设备似乎没有此内存泄漏问题。
【问题讨论】:
【参考方案1】:从LeakCanary's sources 可以看出,这是众所周知的内存泄漏。
SpenGestureManager
有一个静态的mContext
字段,它泄露了对活动的引用。是的,一个 STATIC mContext 字段。
我认为这可以使用反射来解决。这是一段应该可以工作的代码:
// Perform an if-check to see whether this is a Samsung device
Class clazz = Class.forName("com.samsung.android.smartclip.SpenGestureManager");
Field mContext = clazz.getDeclaredField("mContext");
mContext.setAccessible(true);
mContext.set(null, null);
【讨论】:
尽管getDeclaredField("modifiers")
似乎抛出了NoSuchFieldException
,但您的方法似乎效果很好。尽管如此,我还是从手机上的framework2.jar 包中反编译了SpenGestureManager.java,mContext 看起来好像没有声明为final。所以我用mContext.setAccessible(true)
代替了对setFinalStatic()
的调用,直接调用了mContext.set(null, null)
。内存泄漏现在似乎已经消失了。以上是关于三星 Note 3:按下 SPen 侧键后出现 Activity Memory Leak的主要内容,如果未能解决你的问题,请参考以下文章