【问题标题】:CountDownTimer : In Activity, ViewModel or separate class?CountDownTimer:在 Activity、ViewModel 还是单独的类中?
【发布时间】:2019-06-24 09:07:58
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: android android-lifecycle countdowntimer android-viewmodel


    【解决方案1】:

    在 MVVM 模式中,您可以在 ViewModel 中有一个 LiveData 可观察对象,UI 会观察到它,并且在值更改时您会相应地更新 UI。该 observable 如何更改值,即您的业务逻辑,所有这些都应该在您的 ViewModel 或 ViewModel 将用于更新 observable 状态的单独组件中。

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

    【讨论】:

    • 是的,但是因为我想要一个 LifecycleObserver 来启动和停止我的倒计时计时器并且需要持有 Activity Lifecycle 对象,这意味着我的 ViewModel 将持有一个活动字段,不是不推荐?
    • 如果您在活动中实例化 LifecycleObserver,您可以从回调中调用 viewModel 方法。无论如何,您不需要生命周期观察者,因为您可以从活动生命周期本身调用 viewModel 方法
    • LifecycleObserver 不是必需的,但我读到最好避免在其生命周期方法中的 Activity 中启动和取消诸如 CountdownTimer 之类的组件。
    • 我不是告诉你在活动中调用计时器,我是告诉你调用视图模型。请记住,视图模型不支持生命周期
    【解决方案2】:

    一个单独的组件“EventCountdownTimer”

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

    public interface TimerListener {
        void onTimerResponse(String response);
    }
    

    修改您的EventCountdownTimer,使其具有一个以TimerListener 作为参数的构造函数,并在您的活动中覆盖onTimerResponse 方法。现在从您的EventCountdownTimer,例如,当您尝试与您的活动以及一条消息进行通信时,您可能只调用函数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);
        }
    }
    

    然后从您的活动中初始化EventCountdownTimer,如下所示。

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

    我认为你已经提供了很好的理由不选择你提到的其他选择。

    【讨论】:

    • 好吧,有了这个选项,我什至可以使用 LifecycleObserver 根据活动生命周期状态来启动和停止计时器。会试一试,让你知道
    • 当然!让我知道这是否有帮助!
    【解决方案3】:

    谷歌解决方案:see it on github

    /**
     * A ViewModel used for the {@link ChronoActivity3}.
     */
    public class LiveDataTimerViewModel extends ViewModel {
    
        private static final int ONE_SECOND = 1000;
    
        private MutableLiveData<Long> mElapsedTime = new MutableLiveData<>();
    
        private long mInitialTime;
        private final Timer timer;
    
        public LiveDataTimerViewModel() {
            mInitialTime = SystemClock.elapsedRealtime();
            timer = new Timer();
    
            // Update the elapsed time every second.
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    final long newValue = (SystemClock.elapsedRealtime() - mInitialTime) / 1000;
                    // setValue() cannot be called from a background thread so post to main thread.
                    mElapsedTime.postValue(newValue);
                }
            }, ONE_SECOND, ONE_SECOND);
    
        }
    
        public LiveData<Long> getElapsedTime() {
            return mElapsedTime;
        }
    
        @Override
        protected void onCleared() {
            super.onCleared();
            timer.cancel();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      相关资源
      最近更新 更多