【问题标题】:How to preserve the value of intent object upon activity restart?如何在活动重启时保留意图对象的值?
【发布时间】:2017-12-27 12:53:32
【问题描述】:

我有以下场景:我有一个模型类,看起来像这样:

public class UserModel implements Serializable {
    private String userEmail, userName;

    public UserModel() {}

    public UserModel(String userEmail, String userName) { this.userEmail = userEmail; this.userName = userName;}

    //setters and getters
}

在我的第一个活动中,我正在登录 Firebase,我从 FirebaseUser 对象获取数据,然后我正在创建 UserModel 类的对象并将其传递给意图,如下所示:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("userModel", userModel);
startActivity(intent);

在第二个活动中,每次启动时,我都会检查用户是否已登录。如果是,它会留在这里,如果不是,我会重定向到第一个活动。在这里,我使用以下代码行获取对象:

UserModel userModel = (UserModel) getIntent().getSerializableExtra("userModel");

第一次活动开始时,一切正常,但是当我重新开始活动时,我得到一个NullPointerException。如何保留通过任何活动重启从意图中获得的 userModel 对象?

提前致谢!

【问题讨论】:

  • 为此使用 LiveDataViewModel 类。
  • 我找到的最佳解决方案...lucazanini.eu/en/2014/android/…
  • @SripadRaj 为什么要使用 SharedPreferences 而不是 Intent?这有什么问题?
  • @KuLdipPaTel LiveData and ViewModel 是什么意思?
  • @IoanaP。对不起,我想,我误解了你的问题。但是要回答您的问题,可以随时访问 Sharedprefs 数据,但是在 Intents 中,如果您不通过意图,您将无法获取数据。当活动重新启动时,您可能无法通过意图获取数据。所以它抛出了 NPE。

标签: java android firebase android-intent persistence


【解决方案1】:

你应该看看Activity Lifecycle。您会发现一个名为onSavedInstanceState() 的方法。现在您要做的是使用该方法将您的类的对象存储在包中,然后将其取回onCreate(),如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        UserModel userModel = (UserModel) savedInstanceState.getSerializable("userModel");
    } else if (getIntent() != null) {
        UserModel userModel = (UserModel) getIntent().getSerializableExtra("userModel");
    } else {
        // These is no data
    }

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("userModel", userModel);
}

【讨论】:

  • 当我在应用程序之间切换时收到NullPointerException。似乎当onPause被调用时,我的对象也是null。为什么会这样?
【解决方案2】:

您必须将模型保存到外部存储中。一些可行的选择是:

  • SharedPreferences:保存在onPause(),恢复在onResume()onCreate();这是一个快速的example
  • 保存实例状态

例如通过 SaveInstanceState 覆盖以下回调:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);

    /* savedInstanceState Bundle will be passed onto onCreate() when activity
     * gets killed and restarted. */
     savedInstanceState.putSerializable("userModel", userModel);
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    /* Also being passed onto onCreate(). */
    UserModel mUserModel = (UserModel) savedInstanceState.getSerializable("userModel");
}

通过首先对意图进行空值检查,您可以节省一些处理时间,同时不进行任何冗余操作。

【讨论】:

  • 捆绑对象没有getSerializableExtra()
  • 我匆忙中错过了它,同时从问题中复制。已编辑。
  • 如果我将mUserModel 设为全局变量,当我尝试通过我的活动使用mUserModel 对象时,我会得到NullPointerException
  • 是的,saveInstanceState 仅在被 Android 调度程序抢占后才会重新创建活动实例。因此,要正确响应用户引发的上下文切换,您必须改为恢复到 SharedPreferences 并将状态保存在 onPause() 中。
  • 所以在我的情况下,我只能使用SharedPreferences?
猜你喜欢
  • 2010-12-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多