【问题标题】:Can I make the LiveData static?我可以将 LiveData 设为静态吗?
【发布时间】:2018-03-06 20:04:02
【问题描述】:

我不知道这是不是一个愚蠢的问题。这可能会破坏 LiveData/ViewModel 的目的。

我可以将 LiveData 设为静态吗?我的原因是我有一个来自更新信息的服务的侦听器。所以我需要从服务中“设置/更改”LiveData。

我曾经做过以下操作,效果很好:
1. 服务更改数据库
2. ViewModel 监听 DB 变化
3. 来自 liveData 变化的 UI 更新

我发现这种方式太慢了。为了提高性能,我想要这样的东西:
1.Service直接改变类对象
2. ViewModel 监听类对象的变化
3. 来自 liveData 变化的 UI 更新

为了实现我想要的,要么我需要将 MutableLiveData 设为静态,要么让 ViewModel 类在活动之间共享相同的 ViewModel 实例。

这是个好主意吗?

public class MyViewModel extends AndroidViewModel {

    // Note: this MutableLiveData is static
    private static MutableLiveData<MyModel> mutableLiveData;

    public MyViewModel(@NonNull Application application) {
        super(application);
    }

    LiveData<MyModel> getLiveDataList() {
        if (mutableLiveData == null) {
            mutableLiveData = new MutableLiveData<>();
            loadDataFromDb();
        }
        return mutableLiveData;
    }

    private void loadDataFromDb() {
        // load data from DB
        // mutableLiveData.setValue(MyModelFromDb); // Omit the real implementation
    }

    // Note: this method is static
    public static void setData(MyModel newData) {
        mutableLiveData.setValue(newData);
    }

    @Override
    protected void onCleared() {
        super.onCleared();
    }
}

【问题讨论】:

  • “我发现这种方式太慢了” 什么是“太慢”?数据库在哪里?
  • 您是否考虑过将本地广播从您的服务发送到您的活动中已注册的广播接收器,并将更新时间与 LiveData 更新进行比较?
  • 是的,如果您认为它会更快的过程,您可以将其设为静态......但请务必从相同或其他服务更新数据库..(因为静态数据将持续到该应用程序在前台...如果您重新启动数据将丢失
  • 但请务必从同一位置更新数据库 -> 是的,我打算这样做。谢谢。
  • 一个类似但更灵活的做法,就是引入一个repository层,可以为你缓存数据:developer.android.com/topic/libraries/architecture/…repository创建时,可以加载一次数据,然后观察db后续变化。

标签: android android-architecture-components android-livedata android-viewmodel


【解决方案1】:

Android Jetpack 中ViewModel 的全部意义(相对于其他版本)是让ViewModel 能够感知生命周期并执行魔术,例如在观察者被销毁(活动/片段)或在配置更改后幸存时销毁自身(例如,方向)而无需重新初始化自身,从而更容易处理与配置更改相关的问题。

因此,如果您将ViewModelLiveData 设为静态,您实际上会违背他们的目的,并且很可能会泄露ViewModel 的数据,尽管这样做的需要是可以理解的。所以这需要你设计你的方法,你提到的第一种方法可能是你能做到的最好的方法。我不明白为什么您对第一个解决方案有疑问。在我看来,它提供了最好的用户体验:

  1. 您在您的片段或onCreate 的活动中初始化ViewModel,并将Observer 添加到数据中。
  2. 如果数据库已经有一些数据,您的观察者会立即收到它,并且 UI 会立即使用现有数据进行更新。
  3. 服务发出 API 请求并更改数据库
  4. 数据库更改触发ViewModel 中的数据更新
  5. 观察者刷新接收到的数据,然后您将其传递给您的视图/适配器
  6. 使用最新数据更新 UI,并带有一些漂亮的动画来指示添加/删除项目。

据我所知,没有比这更好的了。由于您的问题是几个月前的问题,我很想知道您最终做了什么?

【讨论】:

  • 我想我不明白 LiveData 的具体问题是什么? LiveData 对象不依赖于视图模型或任何与此相关的东西。 Livedata 观察者只依赖于传递的上下文来管理自己的生命周期。将其设为静态不会导致任何泄漏,对吧?
【解决方案2】:
  • 我认为如果MyViewModel 将有很多LiveData 字段,它将随着大量的getter 和setter 而增长。更糟糕的是,对我而言,您将破坏代码的可测试性,因为如果您要创建 MyViewModel 的新实例,您会期望您的 LiveData 对象此时是无状态的,但事实上一个静态对象,你不知道它在简单创建后究竟处于什么状态。
  • 静态方法也不能被覆盖。关于字段:如果您想拥有公共字段,假设 errorMessage,在 A 类和 B 类中,而它们都扩展了 C 类(包含您的公共字段),您可能会遇到意外行为。另一方面,您可以在其他类中复制此代码(这很糟糕)。
  • 内存问题:如果使用了大量静态变量/方法。因为在程序结束之前它们不会被 GC。

但这只是我的意见。

【讨论】:

    猜你喜欢
    • 2015-03-08
    • 2023-03-09
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多