【问题标题】:WeakReference in inner static class is null(cleared) to outer class内部静态类中的弱引用对外部类为空(已清除)
【发布时间】:2021-06-27 04:31:12
【问题描述】:

我是 Java 新手。 我不明白我做错了什么。我在静态内部类中设置了对外部类的弱引用。调试告诉我弱引用设置正确。但是当调用回调(LocationGps locatGps=locationGps1.get();)时,弱引用为空。

public class LocationGps implements OnMapReadyCallback, PermissionsListener {

    private LocationChangeListeningActivityLocationCallback callback =
            new LocationChangeListeningActivityLocationCallback(this);

    private static class LocationChangeListeningActivityLocationCallback
            implements LocationEngineCallback<LocationEngineResult> {
        private final WeakReference<LocationGps> locationGps1;

        LocationChangeListeningActivityLocationCallback(LocationGps locationGps){
            locationGps1 = new WeakReference<LocationGps>(locationGps);
        }

        @Override
        public void onSuccess(LocationEngineResult result) {
            Log.wtf("WHS locationGPS", String.valueOf(result.getLocations()));
            LocationGps locatGps = locationGps1.get();
            locatGps.collbackSetLocation(result.getLastLocation());

        }

        @Override
        public void onFailure(@NonNull Exception exception) {

        }
    }
}

谢谢。

【问题讨论】:

  • 为什么这一定令人惊讶?您是否在某处对LocationGps 有其他引用?

标签: java static inner-classes weak-references


【解决方案1】:

但是当调用回调(LocationGps locatGps=locationGps1.get();)时,WeakReferencenull

您的代码只需要处理这个问题。

WeakReference 的意义在于,如果垃圾收集器确定没有对对象的更强引用1可以被破坏。因此,如果您使用WeakReference,您的代码需要应对 ref 被破坏的可能性。或者...相反...如果您的代码无法应对,那么您应该使用 GC 不会中断的普通(强)引用。

如果您使用SoftReference 而不是WeakReference,GC 只会在堆空间不足时断开链接。这可能会降低引用被破坏的可能性。


另一方面,如果内部类没有声明为static,它将有一个指向封闭类型实例的隐式链接,您可以替换

LocationGps locatGps = locationGps1.get();

LocationGps locatGps = LocationGps.this;

请注意,LocationGps.this 是对外部类实例的强引用。


1 - 由于您已经看到 ref 断开,因此 GC 检测到没有更强的引用,并决定断开链接。

【讨论】:

  • 感谢您的回答。我使用示例docs.mapbox.com/help/tutorials/android-location-listening。 Activity 使用静态类作为 GPS 更新位置变量的回调,以避免内存泄漏。我也是这样做的,但是 Activity 使用额外的类来分割代码的可读性。但这种方法行不通。如果没有弱引用,我可以解决内存泄漏吗?
  • @Stas:您的代码与您链接到的示例代码的工作方式非常不同。示例代码包含对 主要活动 的弱引用。该活动是一个长期存在的对象,只要它处于活动状态,它就会一直保留在其他事物上,并且只有在它不再处于活动状态时才会变成 GC-ed。 正在创建对位置结果的弱引用。定位结果是一个小的,通常是短暂的对象,它的存在只是为了传输一些值。所以它不会被你以外的任何人引用。所以如果你只通过弱引用来引用它,它几乎会立即被 GC。
  • 正如 Joachim 所说的......除了“将几乎立即被 GC”之外,应该严格地说“可能是......”。
猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2017-08-27
相关资源
最近更新 更多