Android Cardboard活动中存在内存泄漏

Android Cardboard活动中存在内存泄漏,android,memory-leaks,google-cardboard,Android,Memory Leaks,Google Cardboard,在分析我的GoogleCardward应用程序时,我发现每次我离开3D图形活动时都会有一个非常大的内存泄漏(15Mb!) 经过漫长而痛苦的调查,我发现问题的根源是每次关闭CardboardActivity子类时都会发生的错误 可以在接受的答案* *哇。。。这很尴尬。。。任何类型(和有经验的)评论者注意:我正在写一个我已经知道答案的问题:我应该为风格做些什么,比如添加一些虚假的悬念(“我们的英雄会获胜吗?!在公认的答案中找到答案!”),就像在一部旧的蝙蝠侠电视连续剧或其他什么中一样?在对我的Car

在分析我的GoogleCardward应用程序时,我发现每次我离开3D图形活动时都会有一个非常大的内存泄漏(15Mb!)

经过漫长而痛苦的调查,我发现问题的根源是每次关闭
CardboardActivity
子类时都会发生的错误

可以在接受的答案
*


*
哇。。。这很尴尬。。。任何类型(和有经验的)评论者注意:我正在写一个我已经知道答案的问题:我应该为风格做些什么,比如添加一些虚假的悬念(“我们的英雄会获胜吗?!在公认的答案中找到答案!”),就像在一部旧的蝙蝠侠电视连续剧或其他什么中一样?

在对我的
CardboardActivity
子类进行切割和切片后,直到只剩下基类,我不得不得出结论,基类本身正在泄漏上下文

我在网上搜索了一下,发现有人解释了相关活动是如何通过未能向类的私有实例取消注册侦听器而泄漏上下文的

在尝试手动调用上述方法(使用反射)时,我发现在Carboard SDK的当前版本(撰写本文时为0.5.4)中,该字段不再存在

长话短说:所有传感器现在都由一个未记录的(尚未公开的)类来处理,该类在
CardboardActivity
中作为
sensorConnection
字段实例化,它仍然受到我的第一个链接中详述的错误的困扰

这让我想到了这个解决方案:

  • 通过反射获取
    CardboardActivity
    中的
    sensorConnection
    字段
  • 使用它再次通过反射获得
    磁传感器
    字段
  • 使用
    null
    参数调用
    setOnCardboardTheaterListener
    ,以清除包含对
    活动
    onDestroy
    方法中的
    上下文的引用的绑定
这归结为以下代码:

private void workAroundLeak() {
    try {
        // Get the sensor Connection
        Class<?> c1 = Class.forName("com.google.vrtoolkit.cardboard.CardboardActivity");
        Field sensorsField = c1.getDeclaredField("sensorConnection");
        sensorsField.setAccessible(true);
        SensorConnection sc = (SensorConnection) sensorsField.get(this);
        if(sc == null) return;

        // Get the magnetSensor
        Class<?> c2 = Class.forName("com.google.vrtoolkit.cardboard.sensors.SensorConnection");
        Field magnetField = c2.getDeclaredField("magnetSensor");
        magnetField.setAccessible(true);
        MagnetSensor ms = (MagnetSensor) magnetField.get(sc);
        if(ms == null) return;

        ms.setOnCardboardTriggerListener(null);
    } catch(Exception e) {}
}

@Override
protected void onDestroy() {
    workAroundLeak();
    super.onDestroy();
}
private void变通方法泄漏(){
试一试{
//连接传感器
c1类=Class.forName(“com.google.vrtoolkit.cardboard.CardboardActivity”);
现场传感器现场=c1.getDeclaredField(“传感器连接”);
传感器字段设置可访问(真);
SensorConnection sc=(SensorConnection)sensorsField.get(this);
如果(sc==null)返回;
//去拿磁传感器
c2类=Class.forName(“com.google.vrtoolkit.cardbard.sensors.SensorConnection”);
磁场磁场=c2.getDeclaredField(“磁场传感器”);
magnetField.setAccessible(true);
MagnetSensor ms=(MagnetSensor)magnetField.get(sc);
如果(ms==null)返回;
ms.setOnCardboardTriggerListener(空);
}捕获(例外e){}
}
@凌驾
受保护的空onDestroy(){
解决方法泄漏();
super.ondestory();
}
完全解决了问题

一句至理名言:由于此解决方案依赖于反射,一旦谷歌更新SDK(可能以干净的方式解决问题),它可能会崩溃(除了什么都不做之外,可能不会有其他后果)

希望这对别人有帮助