在安卓中,如何让代码暂停几秒钟?

40

基本上我需要在一个动作中加入暂停(基于几秒钟),以便用户可以看到下一个动作之前发生了什么。所以在二十一点游戏中,当轮到荷官时,他决定要牵牛,他打牌,加入一张牌,然后他决定下一步该做什么。因此,在他决定下一步该做什么之前,我希望代码暂停,这样可以“看到”荷官正在做什么,这样荷官就不会在不到一秒钟的时间内完成他的动作,而玩家只能看到结果。

提前感谢!

我应该注意到我尝试使用wait(插入数字); 但是eclipse告诉我它会引起堆栈拦截错误或类似的异常,并且什么也不做:(

这很有趣,(我编写的东西是“有趣”的,至少可以这么说),我使用Thread.sleep(5000)并将其放在try-catch下面,它确实休眠了5秒钟,然后继续执行代码。然而,我的视图更新直到我按下按钮后才显示(真的很讨厌事件驱动编程)。

1个回答

102
学会以事件为中心思考是关键。你能够做到 :)
第一条规则是:永远不要阻塞UI线程。UI线程负责保持应用程序的响应性,任何在此处执行的工作都不应该阻塞;尽快完成需要做的事情并返回。绝对避免在UI线程上进行I/O操作。(由于生命周期要求,有些地方你可能无法避免,例如在onPause中保存应用程序状态)。如果您在UI线程上调用Thread.sleep,就是错误的。
Android通过“应用程序无响应”(或“ANR”)错误来强制执行这一点,用户会看到这个错误。每当您在Android应用程序中看到这个错误时,它意味着开发人员做了某些导致UI线程停顿太久的事情。如果设备因某种原因而非常拥挤,这个错误可能实际上不是应用程序开发人员的错,但通常情况下,它意味着应用程序做错了什么。
您可以利用此模型来发布您自己的事件。这为您提供了一种简单的方法来告诉您的应用程序,“稍后处理”。在Android中,发布您自己的事件的关键在于Handler类。方法postDelayed允许您安排一个在某些毫秒后执行的Runnable
如果您有一个看起来像这样的Activity:
public class MyActivity extends Activity {
    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHandler.postDelayed(new Runnable() {
            public void run() {
                doStuff();
            }
        }, 5000);
    }

    private void doStuff() {
        Toast.makeText(this, "Delayed Toast!", Toast.LENGTH_SHORT).show();
    }
}

在创建活动后的5秒钟内,您将在doStuff中看到创建的toast。

如果您正在编写自定义View,那么更容易实现。View有其自己的postDelayed方法,会将所有内容发布到正确的Handler中,您无需创建自己的对象。

第二条规则是:视图应仅在UI线程上进行修改。您收到并忽略的那些异常意味着出了问题,如果您忽略它们,则应用程序可能会以有趣的方式开始表现不良。如果您的应用程序在其他线程中完成大部分工作,可以直接向要修改的视图post事件,以便修改将正确运行。

如果您从代码的那部分拥有对Activity的引用,也可以使用Activity#runOnUIThread,该方法恰好执行其名称所示的操作。如果在上下文中发布到单个视图没有太多意义,则可能更喜欢此方法。

至于视图更新不会出现直到您按下按钮,这是什么类型的视图?这些是绘制这些更新的自定义视图吗?如果是这样,请记得在数据更改后调用invalidate以触发重绘。只有在视图被无效后才会重新绘制。


我的错误在于我试图在一个不断运行的不同线程中修改视图,以便UI不会被锁定...因为我不知道如何将由我的运行线程生成的值传递给UI。非常有帮助的回复,我非常感谢您。 - Ivan S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接