我一直在安卓SDK平台上工作,现在还不清楚如何保存应用程序的状态。因此,考虑到“你好,Android”示例的这个小的重新设计:
package com.android.hello;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
private TextView mTextView = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = new TextView(this);
if (savedInstanceState == null) {
mTextView.setText("Welcome to HelloAndroid!");
} else {
mTextView.setText("Welcome back.");
}
setContentView(mTextView);
}
}
我认为这对于最简单的情况来说已经足够了,但无论我如何离开应用程序,它总是以第一条消息来响应。
我确信解决方案就像重写onPause之类的东西一样简单,但我已经在文档中翻了大约30分钟,没有发现任何明显的东西。
现在,在视图模型中使用两种方法是有意义的。如果要将第一个保存为保存的实例:您可以像这样在视图模型中添加状态参数https://developer.android.com/topic/libraries/architecture/viewmodel-savedstate#java
或者您可以在视图模型中保存变量或对象,在这种情况下,视图模型将保存生命周期,直到活动被破坏。
public class HelloAndroidViewModel extends ViewModel {
public Booelan firstInit = false;
public HelloAndroidViewModel() {
firstInit = false;
}
...
}
public class HelloAndroid extends Activity {
private TextView mTextView = null;
HelloAndroidViewModel viewModel = ViewModelProviders.of(this).get(HelloAndroidViewModel.class);
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = new TextView(this);
//Because even if the state is deleted, the data in the viewmodel will be kept because the activity does not destroy
if(!viewModel.firstInit){
viewModel.firstInit = true
mTextView.setText("Welcome to HelloAndroid!");
}else{
mTextView.setText("Welcome back.");
}
setContentView(mTextView);
}
}
请注意,根据Activity上的文档,对持久数据使用onSaveInstanceState和onRestoreInstanceState是不安全的。
文档说明(在“活动生命周期”部分):
请注意,保存改为onPause()中的持久数据的onSaveInstanceState(捆绑包)因为后者不是生命周期回调,因此不会在描述的每种情况下调用在其文档中。
换句话说,将持久数据的保存/恢复代码放在onPause()和onResume()中!
为了进一步澄清,这里有onSaveInstanceState()文档:
在活动被终止之前调用此方法,以便在未来的某个时候,它可以恢复其状态。对于例如,如果活动B在活动A之前启动点活动A被杀死以回收资源,活动A将具有通过此选项保存用户界面的当前状态方法,以便当用户返回活动A时用户界面可以通过onCreate(Bundle)或onRestoreInstanceState(捆绑包)。
2020年,我们有一些变化:
如果您希望“活动”在进程终止并再次启动后恢复其状态,则可能需要使用“保存状态”功能。以前,需要重写Activity中的两个方法:onSaveInstanceState和onRestoreInstanceState。您还可以在onCreate方法中访问恢复的状态。类似地,在Fragment中,您有onSaveInstanceState方法可用(恢复的状态在onCreate、onCreateView和onActivityCreated方法中可用)。
从AndroidX SavedState 1.0.0开始,它是AndroidX Activity和AndroidX Fragment的依赖项,您可以访问SavedStateRegistry。您可以从Activity/Fragment获取SavedStateRegistry,然后注册SavedStateProvider:
class MyActivity : AppCompatActivity() {
companion object {
private const val MY_SAVED_STATE_KEY = "MY_SAVED_STATE_KEY "
private const val SOME_VALUE_KEY = "SOME_VALUE_KEY "
}
private lateinit var someValue: String
private val savedStateProvider = SavedStateRegistry.SavedStateProvider {
Bundle().apply {
putString(SOME_VALUE_KEY, someValue)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
savedStateRegistry.registerSavedStateProvider(MY_SAVED_STATE_KEY, savedStateProvider)
someValue = savedStateRegistry.consumeRestoredStateForKey(MY_SAVED_STATE_KEY)?.getString(SOME_VALUE_KEY) ?: ""
}
}
如您所见,SavedStateRegistry强制您对数据使用键。这可以防止您的数据被附加到同一Activity/Fragment的另一个SavedStateProvider损坏。此外,您还可以将SavedStateProvider提取到另一个类中,以便通过使用所需的抽象来处理数据,从而在应用程序中实现干净的保存状态行为。
Kotlin代码:
保存:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState.apply {
putInt("intKey", 1)
putString("stringKey", "String Value")
putParcelable("parcelableKey", parcelableObject)
})
}
然后在onCreate()或onRestoreInstanceState()中
val restoredInt = savedInstanceState?.getInt("intKey") ?: 1 //default int
val restoredString = savedInstanceState?.getString("stringKey") ?: "default string"
val restoredParcelable = savedInstanceState?.getParcelable<ParcelableClass>("parcelableKey") ?: ParcelableClass() //default parcelable
如果不想有Optionals,请添加默认值