5

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

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

我曾经做过以下操作,它可以工作:
1. 服务更改 DB
2. ViewModel 监听 DB 更改
3. 从 liveData 更改中更新 UI

我发现这种方式太慢了。为了提高性能,我想要这样的东西:
1. 服务直接更改类对象
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();
    }
}
4

2 回答 2

1

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

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

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

从我可以看到它不能比这更好。由于您的问题是几个月前的问题,我很想知道您最终做了什么?

于 2018-12-20T03:43:29.047 回答
0
  • 我认为如果MyViewModel有很多LiveData领域,它会随着大量的 getter 和 setter 而增长。更糟糕的是,对我来说,你会破坏代码的可测试性,因为如果你创建一个新实例,MyViewModel你会期望你的LiveData对象在这个时间点是无状态的,但因为它是一个静态对象,所以你不需要'不知道在简单创建之后它究竟处于什么状态。
  • 静态方法也不能被覆盖。关于字段:如果您希望拥有公共字段,假设 errorMessage,在 A 类和 B 类中,而它们都扩展了 C 类(包含您的公共字段),您可能会遇到意外行为。另一方面,您可以在其他类中复制此代码(这是不好的)。
  • 内存问题:如果使用大量静态变量/方法。因为在程序结束之前它们不会是 GC。

但这只是我的看法。

于 2018-12-21T00:44:55.270 回答