CountDownTimer :在 Activity、ViewModel 或单独的类中?

Seb*_*AND 5 android android-lifecycle countdowntimer android-viewmodel

我想创建一个CountdownTimer将触发更新 UI 的事件(触发弹出窗口、启动动画等)。

我想知道如何做到这一点,这是我的假设以及原因:

  1. 一个单独的组件EventCountdownTimer。然后我可以受益于使用LifecycleObserver,但我想知道如何将信息传达回活动(我尝试在活动中扩展CountdownTimer和使用它,但出现错误并且无法编译)
  2. 就其Activity本身而言,它是最简单的,但我不确定它属于那里,因为它不是 UI 组件,我无法从中受益LifecycleObserver
  3. ViewModel. 我认为因为它与活动相关并且CountdownTimer有点逻辑数据,所以它应该放在这里,但这也意味着要观察活动的生命周期,并在其中保留任何Activity相关领域ViewModel是不好的做法。

你认为最好的选择是什么?为什么?

Ric*_*rdo 7

在 MVVM 模式中,您可以在 ViewModel 中拥有一个可观察的 LiveData,UI 将观察到该 LiveData,并在值发生变化时相应地更新 UI。可观察值如何改变值,这就是您的业务逻辑,所有这些都应该位于您的 ViewModel 中或 ViewModel 将使用的单独组件中来更新可观察状态。

这将允许您将 UI 与业务逻辑分开,作为您可观察到的两者之间的通信桥梁,而 ViewModel 无需了解 UI 中发生的情况。简而言之,它只执行被告知要执行的内容并更新正在观察的变量,然后 UI 中发生的事情是 UI 责任,这样您就可以实现明确的关注点分离。

  • 确实如此,但由于我希望有一个 LifecycleObserver 来启动和停止我的倒计时器,并且需要保存 Activity Lifecycle 对象,这意味着我的 ViewModel 将保存一个活动字段,这不是不推荐吗? (2认同)
  • 如果您在 Activity 中实例化 LifecycleObserver,则可以从回调中调用 viewModel 方法。无论如何,您不需要为此使用生命周期观察器,因为您可以从活动生命周期本身调用 viewModel 方法 (2认同)

Rea*_*hed 2

一个单独的组件“EventCountdownTimer”

在我看来,这是您的情况下可能拥有的最佳实现。为了将信息传达回您的活动,您可以考虑使用如下所示的界面。

public interface TimerListener {
    void onTimerResponse(String response);
}
Run Code Online (Sandbox Code Playgroud)

修改您的EventCountdownTimer构造函数以TimerListener作为参数并覆盖onTimerResponse活动中的方法。现在EventCountdownTimer,例如,当您尝试通过消息与 Activity 进行通信时,您可能只需调用该函数onTimerResponse(msgToDeliver)

因此你的EventCountdownTimer应该看起来像这样。

public class EventCountdownTimer {
    public static Context context;
    public static TimerListener listener;

    public EventCountdownTimer(Context context, TimerListener listener) {
        this.context = context;
        this.listener = listener;
    }

    public startCountdown() {
        // Start the count down here
        // ... Other code

        // When its time to post some update to your activity
        listener.onTimerResponse(msgToDeliver);
    }
}
Run Code Online (Sandbox Code Playgroud)

并从您的活动中初始化EventCountdownTimer如下所示。

EventCountdownTimer timer = new EventCountdownTimer(this, new TimerListener() {
    @Override
    public void onTimerResponse(String message) {
        // Do something with the message data 
        // Update your UI maybe
    }
});
Run Code Online (Sandbox Code Playgroud)

我认为您已经提供了不选择您提到的其他选择的充分理由。