为什么将活动实例保存到静态单例中不起作用?

时间:2017-10-25 15:45:49

标签: android

private static MainActivity main;
@Override
protected void onCreate(Bundle savedInstanceState) {
    main=this;
}
public static MainActivity getInstance(){
   return main;
}

此代码完全按预期工作,直到应用程序已在后台运行了太长时间。然后发生了一些奇怪的事情:getInstance()不一定返回活动的Activity。

例如,如果实际显示在MainActivity内部的片段调用onClickListener MainActivity.getInstance()。showSomeOtherFragment();抛出IllegalThreadState或ActivityDestroyed异常。我的理论是getInstance()指向一个旧实例。

但为什么"新" onCreate不续订" main"到新的实例?

(我知道在这种情况下我应该使用FragmentInteraction,但我需要传输一个不可捆绑的对象)

2 个答案:

答案 0 :(得分:1)

Activity实例保存到静态字段的想法有很多问题,但我现在会选择忽略它们,而是讨论为什么静态字段在应用程序出现后变为null在后台很长一段时间

对于这类问题,最重要的是要了解Android编程,Android操作系统可以随时终止您的进程。当然,操作系统试图对此友好;当用户没有主动与之交互时,它会尽力杀死你的进程,并且它将为你提供记录状态的机会,以便以后可以恢复你的进程(用户没有意识到这个过程)曾被杀死过。)

当操作系统终止您的进程时,只需通过静态变量保留它而“保存”的任何内容都将丢失

这是(一个原因)为什么系统会为您提供onSaveInstanceState()之类的回调:这样您就可以获取应用程序的状态并将其保存为,即使是进程死亡

即使操作系统没有杀死你的进程,它也可以执行诸如“销毁”给定Activity实例之类的事情,以便回收一些系统资源。一旦Activity实例被销毁,它就不再有效了。

tl; dr:当操作系统杀死你的进程时,静态变量将无法生存;您希望“保存”的任何内容都应存储在SharedPreferences中,或添加到Bundle传递给onSaveInstanceState()等。

答案 1 :(得分:0)

此代码按预期工作

private static MainActivity main;
@Override
protected void onCreate(Bundle savedInstanceState) {
    main=this;
}
@Override
protected void onResume(Bundle savedInstanceState) {
    main=this;
}

public static MainActivity getInstance(){
   return main;
}

Android似乎在onResume()上创建一些非类似java的活动类实例,复制旧onCreate()实例的引用。

private static MainActivity main;
private  String test = "I am new";
@Override
protected void onCreate(Bundle savedInstanceState) {
    main=this;
    test="I am old";
}
@Override
protected void onResume(Bundle savedInstanceState) {
    if(main!=this){          // did not expect that could happen
       Log.i("TEST",test);   // gives "I am old", class is not reinitalized completely
    }
    main=this;

}

public static MainActivity getInstance(){
   return main;
}