【问题标题】:Save custom object on screen rotate in Fragment or Activity在 Fragment 或 Activity 中将自定义对象保存在屏幕上旋转
【发布时间】:2017-09-28 10:46:37
【问题描述】:

我知道这个问题很常见,我已经阅读了很多不同的答案,但没有一个适合我的问题。在我的应用程序中,我有一个活动,并且在 rye 活动中我加载了一个片段。我还向片段发送了一些数据(以 Bundle 的形式)。所以我的问题是当屏幕旋转时,我将片段保存在onSaveInstanceStateActivity 方法中并检查 onCreate 方法天气 savedInstance 是否为空,并在此基础上加载片段。 活动代码:

 @Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
    super.onSaveInstanceState(outState, outPersistentState);
    outState.putParcelable(Const.TAG_REQ_CUSTOM,DetailsItems);
    outState.putString(Const.TAG_FLOW, Const.TAG_MAIN_FLOW);
    getSupportFragmentManager().putFragment(outState,"current_fragment",fragment);
}

onCreate 方法:

if (findViewById(R.id.fragment_frame) != null) {
        if (savedInstanceState != null) {
// this invoke when screen rotate but the app crash 

            DetailsItems = savedInstanceState.getParcelable(Const.TAG_REQ_CUSTOM);
            String flow = savedInstanceState.getString(Const.TAG_FLOW);
           ft = getSupportFragmentManager().getFragment(savedInstanceState,"current_fragment");
            mFragmentManager=getSupportFragmentManager();
            mFragmentTransaction = mFragmentManager.beginTransaction();
            bundle= new Bundle();
            bundle.putString(Const.TAG_FLOW, flow);
            bundle.putParcelable(Const.TAG_REQ_BOOKING_DETAILS, bookingDetailsItems);
            ft.setArguments(bundle);
            mFragmentTransaction.replace(R.id.fragment_frame, ft).commit();
        }else{
           // load fragment on first time
        }
    }

所以我的问题是:我必须在哪里保存自定义对象(在父 Activity 或片段中)? 当我保存的实例不为空时,应用程序崩溃和日志为:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference

【问题讨论】:

    标签: android android-fragments android-activity android-lifecycle android-savedstate


    【解决方案1】:

    您应该使用ViewModelViewModel 是专门为此目的而制作的。

    来自文档:

    ViewModel 是一个类,负责为 Activity 或 Fragment 准备和管理数据。它还处理 Activity / Fragment 与应用程序其余部分的通信(例如调用业务逻辑类)。

    【讨论】:

      【解决方案2】:

      在活动中使用此代码:

          if (findViewById(R.id.fragment_frame) != null) {
              if (savedInstanceState != null) {
      fragment =getSupportFragmentManager().getFragment(savedInstanceState,"current_fragment");
      
              }else{
                 // load fragment on first time
              }
          }
      

      在片段中:

      //save custom object
      
       @Override
          public void onSaveInstanceState(Bundle outState){
              super.onSaveInstanceState(outState);
              outState.putParcelable("key",customObject);
          }
      
      //now retrieve here
      
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
          if (savedInstanceState != null)
          customObject= savedInstanceState.getParcelable("key");
      }
      

      【讨论】:

      • 这假设对象实现了Parcelable 接口,而 OP 正在询问如何保存/恢复任意对象。
      【解决方案3】:

      看看onRetainNonConfigurationInstance()getLastNonConfigurationInstance()

      来自文档:

      由系统调用,作为由于配置更改而销毁活动的一部分,当知道将立即为新配置创建新实例时。您可以在此处返回您喜欢的任何对象,包括活动实例本身,稍后可以通过在新活动实例中调用 getLastNonConfigurationInstance() 来检索。

      【讨论】:

      • 从文档链接中可以看到,这些方法在Activity 中定义。
      猜你喜欢
      • 2012-09-12
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多