我一直在安卓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分钟,没有发现任何明显的东西。
您需要重写onSaveInstanceState(Bundle savedInstanceState),并将要更改的应用程序状态值写入Bundle参数,如下所示:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putBoolean("MyBoolean", true);
savedInstanceState.putDouble("myDouble", 1.9);
savedInstanceState.putInt("MyInt", 1);
savedInstanceState.putString("MyString", "Welcome back to Android");
// etc.
}
Bundle本质上是一种存储NVP(“名称-值对”)映射的方法,它将被传递到onCreate()和onRestoreInstanceState(),然后在那里您可以从如下活动中提取值:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");
}
或者从碎片中提取。
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");
}
您通常会使用此技术来存储应用程序的实例值(选择、未保存的文本等)。
解决这个问题的简单快捷方法是使用IcePick
首先,在app/build.gradle中设置库
repositories {
maven {url "https://clojars.org/repo/"}
}
dependencies {
compile 'frankiesardo:icepick:3.2.0'
provided 'frankiesardo:icepick-processor:3.2.0'
}
现在,让我们看看下面的示例,如何在“活动”中保存状态
public class ExampleActivity extends Activity {
@State String username; // This will be automatically saved and restored
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Icepick.restoreInstanceState(this, savedInstanceState);
}
@Override public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState);
}
}
它适用于Activities、Fragments或任何需要在Bundle上序列化其状态的对象(例如,迫击炮的ViewPresenter)
Icepick还可以为自定义视图生成实例状态代码:
class CustomView extends View {
@State int selectedPosition; // This will be automatically saved and restored
@Override public Parcelable onSaveInstanceState() {
return Icepick.saveInstanceState(this, super.onSaveInstanceState());
}
@Override public void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state));
}
// You can put the calls to Icepick into a BaseCustomView and inherit from it
// All Views extending this CustomView automatically have state saved/restored
}
基本上有两种方法可以实现这一改变。
使用onSaveInstanceState()和onRestoreInstance State()。在manifestandroid:configChanges=“orientation|screenSize”中。
我真的不建议使用第二种方法。因为在我的一次体验中,它导致设备屏幕一半变黑,同时从纵向旋转到横向,反之亦然。
使用上面提到的第一种方法,我们可以在方向改变或任何配置改变时保存数据。我知道一种方法,可以在savedInstance状态对象中存储任何类型的数据。
示例:如果要持久化Json对象,请考虑一个案例。使用getter和setter创建一个模型类。
class MyModel extends Serializable{
JSONObject obj;
setJsonObject(JsonObject obj)
{
this.obj=obj;
}
JSONObject getJsonObject()
return this.obj;
}
}
现在,在onCreate和onSaveInstanceState方法中的活动中,执行以下操作。它看起来像这样:
@override
onCreate(Bundle savedInstaceState){
MyModel data= (MyModel)savedInstaceState.getSerializable("yourkey")
JSONObject obj=data.getJsonObject();
//Here you have retained JSONObject and can use.
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Obj is some json object
MyModel dataToSave= new MyModel();
dataToSave.setJsonObject(obj);
oustate.putSerializable("yourkey",dataToSave);
}