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