【问题标题】:LocationListener leaking in fragment even when appropriately handled即使处理得当,LocationListener 也会在片段中泄漏
【发布时间】:2017-07-06 19:59:22
【问题描述】:

我有一个使用位置管理器 (android.location.LocationManager) 的片段。 mLocationManager 和 mLocationListener (android.location.LocationListener) 是片段的私有变量。

在 onResume() 中

mLocationListener = new ABCLocationListener();
mLocationManager = (LocationManager) getActivity().getSystemService(
                    Context.LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10 * 1000L, 0F, mLocationListener);

在 onPause() 中

mLocationManager.removeUpdates(mLocationListener);
mLocationListener = null;

我的 ABCLocationListener 泄漏了。

logcat D/LeakCanary: | mListener = com.xyz.android.presentation.MyFragment$ABCLocationListener@863187568 (0x33733270)

我检查了什么?
1) 正在创建的 ABCLocationListener 对象的哈希值不同于 0x33733270。
2) onResume 和 onPause 方法都只被调用一次。在调用 removeUpdates 和 requestLocationUpdates 之前,这两个方法中监听器的哈希值是相同的

【问题讨论】:

  • 该片段的父级类型 - 它是 ViewPager 还是 Tabs?还要避免每次都从 onResume() 创建新对象。只需创建一次,然后注册和注销。

标签: android android-fragments memory-leaks location


【解决方案1】:

检查this example,但我会说片段的onResume 被再次调用,或者您在onResume 中实例化的mLocationListener 与您在onPause 中取消注册的实例不同。如果您提供完整片段的源代码,它会有所帮助。为确保位置监听器实例相同,请将片段本身设为监听器(通过实现 LocationListener)并注册/取消注册片段(使用 this)。

【讨论】:

  • 我有日志。每次调用 onResume 时我都会打印。我看到 onResume 和 onPause 都被调用了一次。在调用 removeUpdates 和 requestLocationUpdates 之前,还要在这两种方法中为侦听器设置字符串
  • 您自己已经发现了问题。您取消注册的侦听器与您正在注册的侦听器不同。告诉你为什么我必须查看代码,但要解决它只需让片段本身成为我已经提到的侦听器。
  • 我的意思是我在 onPause 和 onResume 中都有“toString()”监听器。两种方法中的侦听器都是相同的。此外,我正在记录创建侦听器的任何位置。我看到监听器只创建一次
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多