【问题标题】:Android: persisting data across app lifecycleAndroid:跨应用生命周期持久化数据
【发布时间】:2019-11-08 09:59:49
【问题描述】:

我正在开发一个使用一些后台任务 (AsyncTasks) 的 Android 应用,我想使用有关跨应用生命周期和任务回调的数据持久性的最佳实践。

到目前为止,我对此有多种做法:

1) 我在类中有一些静态字段,其中 AsyncTasks 以下列形式使用:

private static String str1;
private static String str2;
private static int int1;
...//=>no more than 6 static fields

2) 我使用带有许多 getter/setter 的 sinleton App 实例,其形式为:

package xxx.xxx.xxx

import xxx.xxx.xxx
...

public class AppSettings {

    private static AppSettings singleton;
    private String _field1;
    ...//=>many fields

    public void setField1(String field1) { _field1 = field1; }
    public String getField1() { return _field1; }
    ...//=>many getters/setters

    private AppSettings() {}

    public AppSettings getInstance(){
        if (instance== null) {
            synchronized(AppSettings.class) {
                if (instance == null)
                    instance = new AppSettings();
            }
        }
        return instance;
    }
}

我绝对知道滥用静态字段一点都不好,所以我决定全部替换它们,但我不完全确定我的第二种方法 - 在具有许多 getter/setter 的单例中拥有一个应用程序实例 -被认为是一个好方法,如果不是,我想知道更好的选择。

非常感谢。

编辑 1:只是为了澄清。

为了让你更清楚地了解我使用我的 AppSettings 单例类,我给你举两个例子:

1) 我使用它来存储应用程序设置/配置值(这就是名称的原因),以便在任何地方都可用。例如,字体颜色、字体大小等等。

2) 我用它来存储临时数据/值。例如,我的主要活动使用“VideoHelper”类在背景中创建一个小视频并通过 AsyncTask 调用,并且由于视频生成过程需要来自主要活动的一些参数,我使用 AppSettings 的 getter/setter 来发送它们。

编辑 2:更好地解释一切。

感谢@a_local_nobody,我意识到我的“使用案例”不是很清楚,所以我会添加更多内容。

我的 AppSettings 没有用于存储用户设置,我使用 SharedPreferences 来存储用户设置,而是使用应用默认配置参数。

举个例子,我存储活动背景颜色(这只是一个例子),所以如果将来我改变主意并决定使用另一种背景颜色,这个设置(以及更多)集中在那里。它就像许多默认应用设置的“容器”。

关于在这个应用程序单例类中使用 getter 和 setter,我想我会遵循 @a_local_nobody 的建议,在每个类中定义一些静态变量并根据需要使用它们,而不是在全局范围内使用一堆不相关的 getter/setter .

无论如何,欢迎所有的cmets。

【问题讨论】:

  • 你应该尽量避免一般的异步任务,因为它们可能很快就会被弃用——旁注
  • 感谢您的贡献@a_local_nobody。我使用 AsyncTaks 进行网络操作,例如下载文件或通过 api 获取令牌 id(例如),这是强制性的,您不能在主线程中运行网络操作,那么 AsyncTask 的替代方案是什么?为什么你认为它可能很快就会被弃用?
  • 看看 RxJava 或 Coroutines,异步任务很适合刚开始,但显然它们很快就会被弃用:xda-developers.com/asynctask-deprecate-android-11

标签: android android-asynctask singleton persistence instance


【解决方案1】:

嗯,你说的是persisting data across app lifecycle,在我看来,这听起来像是你在寻找ViewModel

ViewModel 类旨在存储和管理与 UI 相关的数据 一种生命周期意识的方式。 ViewModel 类允许数据生存 配置更改,例如屏幕旋转。

还有:

ViewModel 的目的是获取和保存信息 这是 Activity 或 Fragment 所必需的。活动或 Fragment 应该能够观察到 ViewModel 的变化。

ViewModel 是 MVVM 设计模式的一部分,在线提供大量示例。

欲了解更多信息,请查看at the documentation


在旁注中,也许您可​​以查看google sunflower project,了解有关如何实现新架构组件的一些想法,其中包括ViewModels 的用法。


另外值得补充的是,您使用 AppSettings 解决方案创建的内容是一个很大的依赖项。各种各样的事情将取决于这个单一的对象,并且很可能在整个应用程序中都需要它。您可能会考虑,而不是像这样创建它,而是将dependency injection 与您的选项一起使用,对于android,可能是Dagger 2Koin for kotlin(如果您曾经切换到kotlin)或者您自己的依赖形式无需使用这些框架即可注入。

希望对你有帮助


根据 OP 的反馈进行编辑:

我用它来存储应用设置/配置值(这就是为什么 名称)可在任何地方使用。例如,字体颜色、字体大小、 随便。

这听起来像是Shared preferences 的更好用例,尤其是如果这些设置是由用户定义的,否则您应该将它们保存到strings.xml 等中并使用localization

我用它来存储临时数据/值。例如,我的主要活动 使用“VideoHelper”类在后台创建一个小视频,然后 通过 AsyncTask 调用,并根据视频生成过程的需要 主要活动的一些参数,我使用 AppSettings getter/setter 让他们通过。

如果你有一个 VideoHelper 类,你最好为这个对象创建一个 Builder 设计模式,或者让这个帮助器有静态变量来根据需要改变它的功能,如果这些是你的 @ 的变量987654335@,那么它们应该位于您的VideoHelper

一起改变的东西通常应该保持在一起。

【讨论】:

  • 非常感谢@a_local_nobody,你写了一个非常有用的回复,其中包含很好的信息,我必须检查一下,因为我还没有在 Android 中使用 ViewModels。根据你的说法,我想创建一个 ViewModel 是现在要走的路,所以我会花时间阅读,我很可能会走这条路。无论如何,请阅读我的最后一次编辑(这样您就可以更好地了解我使用单例类的目的),如果您仍然认为“ViewModel”是要走的路,请告诉我。
  • 再次非常感谢@a_local_nobody,回复非常迅速。我试图避免使用静态变量,因为我知道滥用它们是不可取的,但根据你最后的回复,我猜有一些它不会“伤害任何人”,对吧?
  • 不客气 :) 记得在以后的问题中添加尽可能多的细节,因为这会对我们的答案产生影响 :D 我不认为制作一个大型静态对象是一个好主意就标准而言,我宁愿建议将静力学移动并放置到与它们相关的位置。 VideoHelper 应该包含它需要运行的变量(甚至是静态的),这是我对事情的看法,因为我觉得这使用了干净的代码方法
  • 对不起@a_local_nobody,现在我意识到-由于您的评论-我并没有很清楚地解释我的使用案例。作为“最后”注意事项并关于 AppSettings,我应该补充一点,我存储的内容并不完全是用户设置(我显然为此使用 SharedPreferences),而是我存储了应用程序默认设置,例如,主要活动的背景颜色(比如说)因此,如果任何时候我希望应用程序具有不同的背景颜色,我都会将所有此类启动设置集中在那里。让我知道您对此有何看法,我会更新我的答案,以便其他人可以更好地了解所有内容。
  • 我还是想说你应该看看这个developer.android.com/guide/topics/resources/localization 了解如何存储这些值,然后你可以用这些创建样式和主题
【解决方案2】:

您的方法不符合现代 android 开发中的“最佳实践”。

处理配置更改的推荐方法是使用新的architecture componentViewModel

它具有在配置更改发生时触发的 onDestroy 幸存的属性。

基本上,您需要将此 AppSettings 代码移动到 ViewModel。

【讨论】:

  • 非常感谢@Ian Medeiros,我会像上面一样回复。你写了一个非常有用的回复,其中包含我必须检查的好信息,因为我还没有在 Android 中使用 ViewModels。根据你的说法,我想创建一个 ViewModel 是现在要走的路,所以我会花时间阅读,我很可能会走这条路。无论如何,请阅读我的最后一次编辑(这样您就可以更好地了解我使用单例类的目的),如果您仍然认为“ViewModel”是要走的路,请告诉我。
猜你喜欢
  • 2021-10-26
  • 2013-07-10
  • 2011-05-18
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
相关资源
最近更新 更多