关于Android的WeakReference有什么问题吗?

时间:2012-11-18 09:17:53

标签: android garbage-collection weak-references

我想转移一个Object throw意图, 但该对象不实现Serializable或parcelable。 所以我意识到这一点:

private static Map<String, WeakReference<Object>> map = new HashMap<String, WeakReference<Object>>();

public static void saveObjectInIntent(Intent intent, String key,
        Object value) {
    String realKey = randomString();
    map.put(realKey, new WeakReference<Object>(value));
    if (intent != null) {
        intent.putExtra(key, realKey);
    }
}

public static Object getObjectFromIntent(Intent intent, String key) {
    String realKey = intent.getStringExtra(key);
    WeakReference<Object> weak = map.get(realKey);
    if (weak != null) {
        return weak.get();
    }
    return null;
}

但是我发现即使活动已经完成,弱引用中的对象也不会被gc回收。

所以我写了一个类似的测试:

Object obj = new Object();
ObjectTrsnferHelper.saveObjectInIntent(null, "a", obj);
obj = null;

obj也没有被回收。

为什么?


抱歉,没有问题。 但我之前写错了测试代码。

它应该是:

Set<String> keys = map.keySet();
for (String key : keys) {
    WeakReference<Object> weak = map.get(key);
    if (weak.get() == null) {
        App.log(key + "被清除了");
    }
}

我之前写过“if(weak == null)”。

1 个答案:

答案 0 :(得分:1)

您在Java上对垃圾收集没有多少控制权。即使您调用System.gc(),也不能指望垃圾收集器在语句结束时运行。

通常,垃圾收集发生在方法的末尾。但是,仍然没有要求它在每种方法上运行。

此外,正在完成的活动并不意味着它现在将被垃圾收集。两者都完全不同。例如,如果您保留一个静态字段并将其设置为您的活动实例(并且这是一个非常糟糕的主意,孩子们不会这样做!!),活动将永远不会被垃圾收集..

但在全球范围内,我并不了解你想要实现的目标。如果您的对象不是可包含的也不是可序列化的,那么您就无法在意图中使用它。意图是为了抵制垃圾收集,它们需要被序列化,它们是由Android序列化的。没有解决方法。

此外,意图也被设计为通过进程间通信传递参数,并且只能因为它们是完全可序列化的而发生。

真的,你不能用那种方式做你想做的事。如果要在活动之间共享对象,请将其设置为可序列化或可分段。另一个选项可以是将它存储在应用程序类中,因为两个活动都可以使用getApplication访问它。