gpt4 book ai didi

android - CardboardActivity 中的内存泄漏

转载 作者:行者123 更新时间:2023-11-29 20:40:39 25 4
gpt4 key购买 nike

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

经过漫长而痛苦的调查,我发现问题的根源是 Context leak每次我关闭 CardboardActivity 子类时都会发生这种情况。

解决方案可以在接受的答案中找到*

* 哇...这很尴尬...注意任何类型(和有经验)的审阅者:我正在写一个我已经知道答案的问题:我是否应该为风格做点什么,比如添加一些虚假的悬念(“我们的英雄会获胜吗?!在公认的答案中找出答案!”),就像在老 bat 侠电视剧中一样?

最佳答案

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

我在网上搜索并找到了 this post解释所讨论的 Activity 如何通过未能取消注册一个类的私有(private)实例的监听器来泄露上下文。

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

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

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

  • 通过反射获取CardboardActivity中的sensorConnection字段
  • 使用它来获取 magneticSensor 字段,再次通过反射
  • 使用null 参数调用setOnCardboardTheaterListener,以清除在Activity 中保存对Context 的引用的绑定(bind)> 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();
}

完全解决了这个问题。

致智者的一句话:由于此解决方案依赖于反射,因此一旦 Google 更新 SDK(可能会在一种干净的方式)。

希望这对某人有帮助

关于android - CardboardActivity 中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31038532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com