我一直在安卓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分钟,没有发现任何明显的东西。
我的同事写了一篇文章,解释了Android设备上的应用程序状态,包括活动生命周期和状态信息的解释,如何存储状态信息,以及保存到状态Bundle和SharedPreferences。看看这里。
本文涵盖三种方法:
使用实例状态包存储应用程序生存期(即临时)的本地变量/UI控制数据
[Code sample – Store state in state bundle]
@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
// Store UI state to the savedInstanceState.
// This bundle will be passed to onCreate on next call. EditText txtName = (EditText)findViewById(R.id.txtName);
String strName = txtName.getText().toString();
EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
String strEmail = txtEmail.getText().toString();
CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
boolean blnTandC = chkTandC.isChecked();
savedInstanceState.putString(“Name”, strName);
savedInstanceState.putString(“Email”, strEmail);
savedInstanceState.putBoolean(“TandC”, blnTandC);
super.onSaveInstanceState(savedInstanceState);
}
使用共享首选项在应用程序实例之间(即永久)存储本地变量/UI控制数据
[Code sample – store state in SharedPreferences]
@Override
protected void onPause()
{
super.onPause();
// Store values between instances here
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit(); // Put the values from the UI
EditText txtName = (EditText)findViewById(R.id.txtName);
String strName = txtName.getText().toString();
EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
String strEmail = txtEmail.getText().toString();
CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
boolean blnTandC = chkTandC.isChecked();
editor.putString(“Name”, strName); // value to store
editor.putString(“Email”, strEmail); // value to store
editor.putBoolean(“TandC”, blnTandC); // value to store
// Commit to storage
editor.commit();
}
使用保留的非配置实例在应用程序生存期内的活动之间保持对象实例在内存中的活动状态
[Code sample – store object instance]
private cMyClassType moInstanceOfAClass; // Store the instance of an object
@Override
public Object onRetainNonConfigurationInstance()
{
if (moInstanceOfAClass != null) // Check that the object exists
return(moInstanceOfAClass);
return super.onRetainNonConfigurationInstance();
}
创建活动时,将调用其onCreate()方法。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
savedInstanceState是Bundle类的一个对象,它第一次为空,但在重新创建时包含值。要保存“活动”的状态,必须重写onSaveInstanceState()。
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("key","Welcome Back")
super.onSaveInstanceState(outState); //save state
}
将值放在“outState”Bundle对象中,如outState.putString(“key”,“Welcome Back”),并通过调用super保存。当活动将被销毁时,它的状态将保存在Bundle对象中,并且可以在onCreate()或onRestoreInstanceState()中重新创建后恢复。在onCreate()和onRestoreInstanceState()中接收的捆绑包相同。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//restore activity's state
if(savedInstanceState!=null){
String reStoredString=savedInstanceState.getString("key");
}
}
or
//restores activity's saved state
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
String restoredMessage=savedInstanceState.getString("key");
}
就我而言,拯救国家充其量是一个拙劣的动作。如果需要保存持久数据,只需使用SQLite数据库即可。Android让SOOO变得简单。
类似于:
import java.util.Date;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class dataHelper {
private static final String DATABASE_NAME = "autoMate.db";
private static final int DATABASE_VERSION = 1;
private Context context;
private SQLiteDatabase db;
private OpenHelper oh ;
public dataHelper(Context context) {
this.context = context;
this.oh = new OpenHelper(this.context);
this.db = oh.getWritableDatabase();
}
public void close() {
db.close();
oh.close();
db = null;
oh = null;
SQLiteDatabase.releaseMemory();
}
public void setCode(String codeName, Object codeValue, String codeDataType) {
Cursor codeRow = db.rawQuery("SELECT * FROM code WHERE codeName = '"+ codeName + "'", null);
String cv = "" ;
if (codeDataType.toLowerCase().trim().equals("long") == true){
cv = String.valueOf(codeValue);
}
else if (codeDataType.toLowerCase().trim().equals("int") == true)
{
cv = String.valueOf(codeValue);
}
else if (codeDataType.toLowerCase().trim().equals("date") == true)
{
cv = String.valueOf(((Date)codeValue).getTime());
}
else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
{
String.valueOf(codeValue);
}
else
{
cv = String.valueOf(codeValue);
}
if(codeRow.getCount() > 0) //exists-- update
{
db.execSQL("update code set codeValue = '" + cv +
"' where codeName = '" + codeName + "'");
}
else // does not exist, insert
{
db.execSQL("INSERT INTO code (codeName, codeValue, codeDataType) VALUES(" +
"'" + codeName + "'," +
"'" + cv + "'," +
"'" + codeDataType + "')" );
}
}
public Object getCode(String codeName, Object defaultValue){
//Check to see if it already exists
String codeValue = "";
String codeDataType = "";
boolean found = false;
Cursor codeRow = db.rawQuery("SELECT * FROM code WHERE codeName = '"+ codeName + "'", null);
if (codeRow.moveToFirst())
{
codeValue = codeRow.getString(codeRow.getColumnIndex("codeValue"));
codeDataType = codeRow.getString(codeRow.getColumnIndex("codeDataType"));
found = true;
}
if (found == false)
{
return defaultValue;
}
else if (codeDataType.toLowerCase().trim().equals("long") == true)
{
if (codeValue.equals("") == true)
{
return (long)0;
}
return Long.parseLong(codeValue);
}
else if (codeDataType.toLowerCase().trim().equals("int") == true)
{
if (codeValue.equals("") == true)
{
return (int)0;
}
return Integer.parseInt(codeValue);
}
else if (codeDataType.toLowerCase().trim().equals("date") == true)
{
if (codeValue.equals("") == true)
{
return null;
}
return new Date(Long.parseLong(codeValue));
}
else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
{
if (codeValue.equals("") == true)
{
return false;
}
return Boolean.parseBoolean(codeValue);
}
else
{
return (String)codeValue;
}
}
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS code" +
"(id INTEGER PRIMARY KEY, codeName TEXT, codeValue TEXT, codeDataType TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
之后打个简单的电话
dataHelper dh = new dataHelper(getBaseContext());
String status = (String) dh.getCode("appState", "safetyDisabled");
Date serviceStart = (Date) dh.getCode("serviceStartTime", null);
dh.close();
dh = null;