【问题标题】:Android: Wait for userinput but set a timeoutAndroid:等待用户输入但设置超时
【发布时间】:2021-12-04 10:16:39
【问题描述】:

在我的应用程序中,用户会收到一个练习提示,他有 5 秒钟的时间来解决它,如果他没有及时响应,应该显示下一个练习。
我的问题是:在 Android 中实现这种行为的最佳方式是什么?

我首先尝试使用CountDownTimer,但由于某种原因CountDownTimer.cancel() 没有取消计时器。

我的第二次尝试有效,(见下文)但它包含一个忙碌的等待,我不知道这是否是一个很好的模式。

for (int i = 0; i < NUM_EXERCISES; i++) {
    // show a new fragment with an activity

    fragmentManager.beginTransaction()
            .replace(R.id.exercise_container, getNextExercise())
            .commit();

    // I create a thread and let it sleep for 5 seconds, and then I wait busily
    // until either the thread is done or the user answers and I call future.cancel()
    // in the method that is responsible for handling the userinput

    future = es.submit(()->{
        Thread.sleep(5000);
        return null;
    });

    while (!future.isDone()) { }
}

它的工作原理是这样的:我创建了一个 Java Future,它的任务是等待 5 秒,并在回调方法中负责处理我调用 future.cancel() 的用户输入,因此可以留下 while 循环并且代码会进一步执行,这意味着 for 循环会进行另一次迭代。
如果用户没有及时响应,则在 5 秒后退出while 循环,确保用户不会在一项练习上花费太多时间。

如有需要,请随时要求进一步澄清。提前谢谢!

【问题讨论】:

    标签: android android-fragments countdowntimer futuretask busy-waiting


    【解决方案1】:

    应在您的代码中取消计时器。试试这个:

            private var countDownTimer: CountDownTimer? = null
            countDownTimer = object : CountDownTimer(10000, 1000) {
            override fun onFinish() {}
    
            override fun onTick(millisUntilFinished: Long) {
                Log.d("millisUntil", millisUntilFinished.toString())
                if ((millisUntilFinished / 1000) <= 5) {
                    countDownTimer?.cancel()
                }
            }
        }.start()
    

    这是一个 10 秒的计时器,它会在 5 秒时通过调用 countDownTimer?.cancel() 取消。

    【讨论】:

    • 计时器将是您描述的用法的完美选择。
    • "你的代码中应该取消计时器。"你是什​​么意思?此外,我无法在onTick() 方法中取消计时器,我必须在处理用户输入的回调方法中取消计时器。但是,由于某种原因,这行不通。
    • 这只是一个例子。您也可以在 onTick 方法之外取消它。为了获得更多控制,您可以在视图模型中放置一个计数器并观察它,以便您知道它何时停止。在观察者内部导航到另一个片段。
    • 问题是,CountDownTimer 需要从它开始的同一个线程中取消。如果我尝试从另一个线程调用CountDownTimer.cancel(),它不起作用。如果我从主线程调用CountDownTimer,我没有某种await() 方法,那么我如何等待CDTimer 完成? for 循环将立即进入另一个迭代,替换当前的练习。另一方面,如果我创建一个执行CountDownTimer.start() 方法的线程,它不会在计时器为0 后终止。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 2016-07-30
    • 2014-01-26
    • 2016-09-26
    • 1970-01-01
    相关资源
    最近更新 更多