在关闭应用程序和检索数据时保存数据
Posted
技术标签:
【中文标题】在关闭应用程序和检索数据时保存数据【英文标题】:Saving data upon closing app and retrieving that data 【发布时间】:2015-05-30 20:06:43 【问题描述】:我知道,这里有很多关于保存/检索数据的问题。我自己在 find 查找问题,并且真的认为我可以设法找到我的答案而无需“提出问题”,但我开始想知道一些我在这里没有看到答案的东西。
我的情况:
当然,我正在制作一个应用程序。关闭应用程序后,我想保存一个简单的数字数组(0 或 1)或布尔值。在启动应用程序时,我想搜索该数组(如果存在)并检索它以在应用程序中使用。
我开始将我的代码放入将使用数组的活动中。但是,我开始想知道是否必须将覆盖的onStop()
函数复制/粘贴到我的所有活动中?或者我是否在主要活动中执行此操作并以某种方式链接其他活动。
基本上,无论应用程序关闭时应用程序当前处于什么状态/活动,我都希望能够保存 int/bool 数组并在应用程序启动时将其打开。
也许我不知道如何搜索我想要的东西,所以解释它是正确的做法。
我不介意进行更多搜索,但如果有人至少能指出我正确的方向,我将非常感激。
编辑:如果有比我描述的更好的方法来做我想做的事(例如,使用不同的状态而不是 onStop()
),请随意抛出想法。这是我第一次真正地不得不处理活动的生命周期,即使在浏览了 android 开发教程之后我也有点困惑。我真的认为他们在大多数情况下做得不好。
【问题讨论】:
来自 wiki :SharedPreferences 是来自 Android SDK 的 API,用于存储和检索应用程序首选项。 SharedPreferences 只是一组持久存储的数据值。持久性意味着即使您停止应用程序或关闭设备,您存储在 SharedPreferences 中的数据仍然存在。 【参考方案1】:当您的应用程序需要保存一些持久性数据时,您应该始终使用onPause()
方法而不是onStop()
。因为如果 android 操作系统杀死了你的进程,那么 onStop()
和 onDestroy()
方法将永远不会被调用。同样在onResume()
方法中检索数据。
【讨论】:
顺便感谢您的提示。我一定会这样做的。 onPause 也会在您抛出插页式广告时调用,这可能不是保存某些游戏的理想时间(即死后插页式广告...)【参考方案2】:看看你想要实现的目的,SharedPreferences就是你想要的。
文档说明:
"SharePreferences 提供了一个通用框架,允许您保存 并检索原始数据类型的持久键值对。你 可以使用 SharedPreferences 保存任何原始数据:布尔值, 浮点数、整数、长整数和字符串。此数据将在用户之间持续存在 会话(即使您的应用程序被终止)。”
【讨论】:
【参考方案3】:使用SharedPreference
存储少量数据或使用SQLite
存储大量数据。
看这个链接
http://developer.android.com/guide/topics/data/data-storage.html
【讨论】:
【参考方案4】:序列化一个对象并传递它,这比共享首选项更可靠(与共享首选项的一致性有很多问题):
public class SharedVariables
public static <S extends Serializable> void writeObject(
final Context context, String key, S serializableObject)
ObjectOutputStream objectOut = null;
try
FileOutputStream fileOut = context.getApplicationContext().openFileOutput(key, Activity.MODE_PRIVATE);
objectOut = new ObjectOutputStream(fileOut);
objectOut.writeObject(serializableObject);
fileOut.getFD().sync();
catch (IOException e)
Log.e("SharedVariable", e.getMessage(), e);
finally
if (objectOut != null)
try
objectOut.close();
catch (IOException e)
Log.e("SharedVariable", e.getMessage(), e);
然后使用一个类来使用:
public class Timestamps implements Serializable
private float timestampServer;
public float getTimestampServer()
return timestampServer;
public void setTimestampServer(float timestampServer)
this.timestampServer = timestampServer;
然后在你想写入变量的任何地方使用:
SharedVariables.writeObject(getApplicationContext(), "Timestamps", timestampsData);
【讨论】:
【参考方案5】:实现这一目标的最佳方法是:
创建一个类。将其称为 MySettings 或任何适合您的名称 在此类中,将您要共享的整数/布尔值数组定义为静态的。创建 getter 和 setter 方法(属性)以访问它(也作为静态方法) 将静态 load() 方法添加到从 SharedPreferences 读取的 MySettings。当您启动应用程序(在您的第一个活动中或在应用程序的子类中更好)时,请致电MySettings.load()
。此加载方法设置数组
添加静态save()
方法。公也。现在,您可以从应用程序的任何位置进行保存。这个save()
方法读取数组并写入SharedPreferences
代码示例:
public class MySettings
private static List<Integer> data;
public static void load()
data = new ArrayList<Integer>();
// use SharedPreferences to retrieve all your data
public static void save()
// save all contents from data
public static List<Integer> getData()
return data;
public static void setData(List<Integer> data)
MySettings.data = data;
【讨论】:
绝对是最好的答案......现在我将把我所有的方法都设为静态,并将整个代码放到 Aplication 类的子类中 Sooo,这是好还是不好?哈哈。我完全赞成讽刺什么的,但在这一点上我只是感到困惑。 我认为这是一个有效的解决方案。不增加像 Dagger 这样的依赖注入框架的复杂性。我认为你是从 Android 开发开始的,在学习的每个阶段你都会找到更好的解决方案。但是这个现在对你有用 好的,谢谢你的诚实。我绝对不需要任何复杂的东西。我真的很想听听@Selvin 对他的 cmets 的推理,我有点困惑,意见越多越好。 Application subclassing(from docs):There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way.
... 在你的第一个活动中如果第一个活动没有被调用,则将以 NPE 结束,是的,它可能发生了......不是“工厂”(SomeClass.getInstance())也不是“助手”(String.format())静态方法,拜托,在OOP的世界里? ...以上是关于在关闭应用程序和检索数据时保存数据的主要内容,如果未能解决你的问题,请参考以下文章
Android Firebase如何在特定用户下保存和检索数据