Android 正在进行垃圾收集的单例实例?
我认为不应该对singleton实例进行垃圾收集,但是我维护了一个singleton对象,并在初始化时对其进行标记,如下所示:Android 正在进行垃圾收集的单例实例?,android,singleton,fragment,Android,Singleton,Fragment,我认为不应该对singleton实例进行垃圾收集,但是我维护了一个singleton对象,并在初始化时对其进行标记,如下所示: private static LocalCache instance; public LocalCache() { // initialize objects...... } public static LocalCache getInstance() { if (instance == null) { instance = new
private static LocalCache instance;
public LocalCache() {
// initialize objects......
}
public static LocalCache getInstance() {
if (instance == null) {
instance = new LocalCache();
Log.e("instance", "new");
}
return instance;
}
我发现此日志在我的应用程序中多次出现。
更准确地说,我在一个片段活动中有5个片段。当我按home按钮执行一些任务并切换回活动时,singleton类似乎被重新分配。我的代码有什么错误吗?或者我可以阻止重新创建片段吗?
我确信我没有为实例分配null
@Override
protected void finalize() throws Throwable {
Log.e("finalize", "finalize");
}
我还重写了finalize()
,以观察它何时被销毁,但日志没有出现在第二个“新实例”日志之前
我的代码有什么错误吗
通常,对于单实例,使用synchronized
和volatile
进行锁定,以确保不会由于多个线程上的并行调用而分配多个实例。或者,在您的情况下,只需使用静态初始值设定项,因为getInstance()
不接受实例化LocalCache
所需的任何参数
然而,更可能的是,这里的问题是您的进程被终止。一旦您不再处于前台,您的进程可以在任何时候终止。当您的应用程序再次运行时,将创建一个新进程,并且所有静态数据成员最初将为null
我的代码有什么错误吗
通常,对于单实例,使用synchronized
和volatile
进行锁定,以确保不会由于多个线程上的并行调用而分配多个实例。或者,在您的情况下,只需使用静态初始值设定项,因为getInstance()
不接受实例化LocalCache
所需的任何参数
然而,更可能的是,这里的问题是您的进程被终止。一旦您不再处于前台,您的进程可以在任何时候终止。当您的应用程序再次运行时,将创建一个新进程,当我切换回活动时,所有静态数据成员最初将为
null
,这与我将活动置于后台之前选择的选项卡相同,我不认为进程已终止……@Leonhart:“当我切换回活动时,它与我将活动置于后台之前选择的选项卡相同”--取决于您“切换回活动”的方式,您将进入“相同选项卡”“无论进程是否终止。值得注意的是,如果您使用“最近的任务”列表,则应返回到该任务后堆栈顶部的任何活动。我使用ViewPagerAdapter存储所选选项卡的索引,因此我假设整个过程没有被破坏,单例也没有被破坏?@Leonhart:如果您使用“最近的任务”列表,您的活动将被传递到已保存的实例状态Bundle
,因此很可能会将自身还原到您在ViewPager
中的最后一页。我使用home按钮切换出,然后按应用程序的图标切换回。我还发现了一些奇怪的事情,我覆盖了finalize()
,以观察它何时被销毁,但日志没有出现在第二个“新实例”日志之前。当我切换回活动时,它与我将活动置于后台之前选择的选项卡相同,我不认为进程已终止……@Leonhart:“当我切换回活动时,它与我将活动置于后台之前选择的选项卡相同”--取决于您“切换回活动”的方式,您将进入“相同选项卡”“无论进程是否终止。值得注意的是,如果您使用“最近的任务”列表,则应返回到该任务后堆栈顶部的任何活动。我使用ViewPagerAdapter存储所选选项卡的索引,因此我假设整个过程没有被破坏,单例也没有被破坏?@Leonhart:如果您使用“最近的任务”列表,您的活动将被传递到已保存的实例状态Bundle
,因此很可能会将自身还原到您在ViewPager
中的最后一页。我使用home按钮切换出,然后按应用程序的图标切换回。我还发现了一些奇怪的事情,我重写了finalize()
,以观察它何时被销毁,但日志没有出现在第二个“新实例”日志之前。