Android 在安卓系统中,为什么单身人士永远不会被回收?

Android 在安卓系统中,为什么单身人士永远不会被回收?,android,Android,我对此感到困惑。刚开始使用android,它有一个很长的表单,需要多个活动来组合一个对象。我想将对象从一个活动传递到另一个活动以构建它。在阅读了大量文章和博客以及Android开发页面之后,对于非持久性数据,最好的选择是对应用程序进行子类化或创建一个单例。我看了这篇文章,现在我的问题是,为什么单身人士从来没有得到回收?如果我们在活动A中创建singleton(),然后移动到活动B,并且我们从不传递对singleton的引用,垃圾回收者如何知道我们将再次返回到它?在我看来,当活动A被回收,我们转移

我对此感到困惑。刚开始使用android,它有一个很长的表单,需要多个活动来组合一个对象。我想将对象从一个活动传递到另一个活动以构建它。在阅读了大量文章和博客以及Android开发页面之后,对于非持久性数据,最好的选择是对应用程序进行子类化或创建一个单例。我看了这篇文章,现在我的问题是,为什么单身人士从来没有得到回收?如果我们在活动A中创建singleton(),然后移动到活动B,并且我们从不传递对singleton的引用,垃圾回收者如何知道我们将再次返回到它?在我看来,当活动A被回收,我们转移到活动B时,单身汉就会死亡

如果我们看一下下面的单例

public final class SomeSingleton implements Cloneable {

    private static final String TAG = "SomeSingleton";
    private static SomeSingleton someSingleton ;
    private static Context mContext;    

    /**
     * I'm private because I'm a singleton, call getInstance()
     * @param context
     */
    private SomeSingleton(){
        // Empty
    }

    public static synchronized SomeSingleton getInstance(Context context){
        if(someSingleton == null){
        someSingleton = new SomeSingleton();
        }
    mContext = context.getApplicationContext();
    return someSingleton;
    }

    public void playSomething(){
        // Do whatever
        mContext.openFileOutput("somefile", MODE_PRIVATE); // etc...
    }

    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("I'm a singleton!");
    }
}

我们通过getInstance()创建它的一个实例,该类将该类的一个实例放入静态字段someSingleton中。为什么这个实例从不回收?如果答案是“静态场永远不会被回收?”那么,如果我们有很多静态场,是什么阻止我们耗尽所有的内存呢?简单的设计考虑?如果我们使用了大量贡献的库,而我们不知道有多少静态字段,那么这似乎是有风险的。我只是觉得作为一个新手,OOP中缺少一些基本的规则

一般的模式是在静态字段中放置对singleton类的引用。静态字段不绑定到特定实例,因此它们会一直保留,直到JVM进程处于活动状态。有多少活动访问它并不重要。如果你需要“回收”单件,也许你真的不需要使用单件?或者提供一个显式的
close()/open()
等方法。

我认为你的单身汉没有被回收的原因是,当你认为Android中的活动被破坏时,它们并没有被破坏


你提出了这样一个问题:“当我们从活动a转到活动B时会发生什么?”。但当你在安卓系统中这样做时,活动A很少被破坏。它通常只是进入状态。因此,如果用户决定按“后退”按钮足够多的次数返回活动A,您的活动A将(大部分)保持不变。

谢谢,我更新了我原来的问题,使之更加具体。我仍然有点困惑。在Java中,也就是在Android中,对象只有在没有可访问的引用时才会被垃圾收集(GC)。由于静态字段始终是可访问的,如果您将某个内容粘贴在静态字段中而从不清除它(设置为
null
),它将不会被GC-ed。但对于单例来说,这是可以的,因为您通常希望它是可访问的,而不是GC-ed。至于内存,有很多方法可以耗尽它:只需列出列表,并开始在循环中向其中添加新对象。最终,您将出现内存不足错误,进程将被终止。