Android 由于配置更改而重新创建活动时,活动的静态成员会发生什么情况

Android 由于配置更改而重新创建活动时,活动的静态成员会发生什么情况,android,android-activity,static,mvp,Android,Android Activity,Static,Mvp,我想在我的活动中创建一个静态presenter对象,这样当由于配置更改而重新创建活动时,它将保留presenter实例,并且我的业务逻辑不会受到影响 我的活动的代码是: public class HomeActivity extends AppCompatActivity { public static HomePresenter presenter; @Override protected void onCreate(Bundle savedInstance

我想在我的
活动
中创建一个静态presenter对象,这样当由于配置更改而重新创建
活动
时,它将保留presenter实例,并且我的业务逻辑不会受到影响

我的
活动的代码是:

    public class HomeActivity extends AppCompatActivity {

    public static HomePresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        if (presenter == null){
            presenter = new HomePresenter();
        }
    }
}

您的代码将正常工作,演示者将处于活动状态,但请不要这样做

关键字“static”表示此字段的值将附加到类,而不是它的实例。例如,如果您将有您的HomeActivity,那么您将转到SomelseActivity,然后转到new HomeActivity(您将有back stack HomeActivity->SomelseActivity->HomeActivity),对于新HomeActivity,您将有与旧HomeActivity相同的演示者。因此,您将有一个共享演示者,用于两个独立的HomeActivity实例。此外,如果您在presenter中有一些状态,那么在这种情况下,您的应用程序将有很多问题

我建议您删除“static”关键字。如果您的演示者具有配置更改期间需要保存的状态,请尝试以下两种选择之一:

1) 在演示者中创建onSaveInstanceState和onRestoreInstance状态,并在相应活动的方法中调用它们

2) 创建没有ui的片段,但带有标志“retain Instance”(setRetainInstance方法),此片段将保留对演示者的引用

简言之,静态对象仍然存在,当您将类加载到内存中时,它就诞生了,并且在应用程序死亡或卸载类之前,它永远不会消失

在JVM语言中,编译器通过嵌入字节码中的值来优化静态字段,而不是在运行时计算值

当您第一次启动JVM并加载一个类时(当类第一次以任何方式被引用时,这由类加载器完成),任何静态块或字段都“加载”到JVM中并变得可访问

因此,静态变量存在于快照中的圆圈中,它不知道任何配置更改,不管发生什么,只要加载了类,它就存在


静态实例不会发生任何事情。但是,如果不删除对静态演示者的引用,这样做可能会泄漏内存(请参阅)

我建议另一种方法。重写
onretainonconfigurationinstance()
以在
活动
因配置更改(例如旋转)而销毁时保留对象。并使用
getLastNonConfigurationInstance()
在配置更改后获取完全相同的对象

 public class HomeActivity extends AppCompatActivity {

    public HomePresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        presenter = (HomePresenter)getLastNonConfigurationInstance();
        if (presenter == null){
            presenter = new HomePresenter();
        }
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        return presenter;
    }
}

您还可以使用
片段
在配置更改期间使对象保持活动状态,请参见。

它将保持活动状态。但别忘了在onDestroy中从演示者中删除所有HomeActivity引用(也指向内部类),并在onCreate中重新设置它们,否则会导致内存泄漏。在该活动和进程被垃圾回收之前,它将一直保留在内存中。如果处理不当,在某些情况下可能会导致潜在的内存泄漏和异常。不是
getLastNonConfigurationInstance()
,而是
getLastCustomNonConfigurationInstance()
No@AKTO。如果要使用
getLastCustomNonConfigurationInstance()
,则需要实现
onRetainCustomNonConfigurationInstance()