android 保存状态信息吗,如何使用保存实例状态保存Android Activity状态?

我一直在研究Android SDK平台,但还不清楚如何保存应用程序的状态。 因此,考虑到“ Hello,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分钟左右的时间,并且没有发现任何明显的问题。

#1楼

onSaveInstanceState(bundle)和onRestoreInstanceState(bundle)方法仅在旋转屏幕(方向更改) onRestoreInstanceState(bundle)对数据持久性有用。

它们在应用程序之间切换时甚至都不好(因为调用了onSaveInstanceState()方法,但是不再再次调用onCreate(bundle)和onRestoreInstanceState(bundle) 。

要获得更多持久性,请使用共享首选项。 阅读这篇文章

#2楼

这是Android开发的经典“陷阱”。 这里有两个问题:

Android框架存在一个细微的错误,至少在旧版本上,该错误使开发过程中的应用程序堆栈管理非常复杂(无法完全确定是否/何时/如何修复)。 我将在下面讨论此错误。

解决此问题的“正常”或预期方式本身非常复杂,因为onPause / onResume和onSaveInstanceState / onRestoreInstanceState的双重性

浏览所有这些线程,我怀疑开发人员在很多时候会同时谈论这两个不同的问题……因此,所有的混淆和报告“这对我都不起作用”。

首先,要阐明“预期”行为:onSaveInstance和onRestoreInstance是脆弱的,仅适用于瞬态。 预期的用途(辅助)是在旋转手机(方向更改)时处理“活动”娱乐。 换句话说,预期的用法是您的活动在逻辑上仍处于“最重要”的位置,但仍必须由系统重新实例化。 保存的Bundle不会持久保存在process / memory / gc之外,因此,如果您的活动进入后台,您将不能真正依赖于此。 是的,也许您的Activity的内存将在进入后台并逃脱GC后幸存下来,但这是不可靠的(也不是可预测的)。

因此,如果您遇到在应用程序的“启动”之间存在有意义的“用户进度”或状态的情况,那么指南就是使用onPause和onResume。 您必须自己选择并准备一个持久性存储。

但是-有一个非常令人困惑的错误,使所有这些问题变得复杂。 详细信息在这里:

基本上,如果您的应用程序是使用SingleTask标志启动的,然后在以后从主屏幕或启动器菜单启动它,则随后的调用将创建一个NEW任务……您将有效地拥有应用程序的两个不同实例居住在同一个堆栈中...很快就会变得非常奇怪。 这似乎是在开发过程中启动应用程序时发生的(即从Eclipse或Intellij),因此开发人员经常遇到这种情况。 而且还可以通过某些应用商店更新机制(因此也会影响您的用户)。

在意识到自己的主要问题是此错误而不是预期的框架行为之前,我在这些线程中进行了数小时的奋战。 一个伟大的文章和 解决方法 (更新:见下文)似乎来自用户@kaciula在此答案中:

2013年6月更新 :几个月后,我终于找到了“正确的”解决方案。 您不需要自己管理任何有状态的startedApp标志,您可以从框架中检测到此问题并适当地保释。 我在LauncherActivity.onCreate的开始附近使用它:

if (!isTaskRoot()) {

Intent intent = getIntent();

String action = intent.getAction();

if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {

finish();

return;

}

}

#3楼

savedInstanceState仅用于保存与Activity的当前实例相关联的状态,例如当前的导航或选择信息,因此,如果Android销毁并重新创建Activity,它可以像以前一样返回。 请参阅文档onCreate和onSaveInstanceState

对于更长的状态,请考虑使用SQLite数据库,文件或首选项。 请参阅保存持久状态 。

#4楼

您需要重写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");

}

通常,您将使用此技术来存储应用程序的实例值(选择,未保存的文本等)。

#5楼

我的问题是我仅在应用程序生命周期内需要持久性(即一次执行,包括在同一应用程序中启动其他子活动并旋转设备等)。 我尝试了上述答案的各种组合,但并没有在所有情况下都得到我想要的东西。 最后,对我有用的是在onCreate期间获取对savedInstanceState的引用:

mySavedInstanceState=savedInstanceState;

并在需要时使用它来获取变量的内容,大致如下:

if (mySavedInstanceState !=null) {

boolean myVariable = mySavedInstanceState.getBoolean("MyVariable");

}

我按照上面的建议使用onSaveInstanceState和onRestoreInstanceState ,但是我想我也可以或者在改变变量时使用我的方法来保存变量(例如,使用putBoolean )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值