Java 线程睡眠,不做

Java 线程睡眠,不做,java,android,multithreading,sleep,Java,Android,Multithreading,Sleep,我对Java中的线程有问题。我想在点击按钮(bt1)时将背景设置为图片,然后等待5秒钟,将同一按钮的背景设置为图片。问题是第一张图片从未设置过。程序只需等待5秒钟,然后设置picture2。这是代码 bt1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { bt1.setBackgroundResource(R.drawable.p

我对Java中的线程有问题。我想在点击按钮(bt1)时将背景设置为图片,然后等待5秒钟,将同一按钮的背景设置为图片。问题是第一张图片从未设置过。程序只需等待5秒钟,然后设置picture2。这是代码

bt1.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {
          bt1.setBackgroundResource(R.drawable.picture);
              try
                 {
                   Thread.sleep(5000);
              }
              catch( InterruptedException e )
              {
                  e.printStackTrace();
              }
          bt1.setBackgroundResource(R.drawable.pic);
        }
    });

}

永远不要休眠用户界面线程

问题在于,您正在处理GUI事件反应的线程中睡觉。当该线程休眠时,GUI就死了。您需要执行其他操作以获得5秒的延迟,例如使用计时器在5秒内创建新事件。

尝试以下操作:

public void onClick(View v) {
    bt1.setBackgroundResource(R.drawable.picture); 
    new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                bt1.setBackgroundResource(R.drawable.picture);

            }
        }, 5000);
}
使用倒计时

new CountDownTimer(5000, 1000) {

 public void onTick(long millisUntilFinished) {

 }

 public void onFinish() {
      bt1.setBackgroundResource(R.drawable.picture);

 }
}.start();

使用
handler.PostDelayed()
,不要在UI线程中执行耗时的操作,如睡眠、网络、数据库

这是因为您正在主UI线程上运行所有内容。永远不要在UI线程中使用睡眠

这是你的代码

public void onClick(View v) {
            bt1.setBackgroundResource(R.drawable.picture);
            Thread thread = new Thread()
            {
                @Override
                public void run() {
                    try {
                            Thread.sleep(5000);
                            runOnUiThread(new Runnable(){public void run()
                            {
                                bt1.setBackgroundResource(R.drawable.pic);
                            }});    

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };

            thread.start();


        }
    });

为什么不使用调度程序?下面是一个可能的实现

bt1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {
      bt1.setBackgroundResource(R.drawable.picture);
         ScheduledExecutorService scheduler = Executors
            .newSingleThreadScheduledExecutor();
    scheduler.scheduleAtFixedRate(new Runnable() {
        public void run() {
             bt1.setBackgroundResource(R.drawable.pic);
        }
    }, 5, 60, TimeUnit.SECONDS);
      bt1.setBackgroundResource(R.drawable.pic);
    }
});

}

在我见过的几乎所有UI框架中,睡在UI线程中都是个坏主意。我怀疑你想要一个计时器。我觉得你正在暂停前台UI线程。您必须分叉一个背景线程来更改它。因为您设置了图片,然后休眠了UI线程,所以它无法更新。在您唤醒它之后,它会立即对其进行更改和更新。正如其他人所说,定时器、异步任务、可运行、除睡眠之外的任何东西。(不管怎样,99%的时间里睡眠都很糟糕,这不是1%中的一个:)几乎在任何地方睡觉都是个坏主意。例如,设置一个计时器比占用一个线程的资源5秒更好,即使它只是一个后台线程。@Gray:当然,这会让操作系统认为进程没有响应。请详细说明您的答案,以便向用户提供更多信息。现在是一个评论。请看@Patricia的答案。@Gray:我同意你的意见,可以随意否决,但这里的问题太严重了,需要从头开始重新思考,并给出一个非常大胆的答案。回答这类问题的目的是为子孙后代提供信息。你想向一个明显的初级程序员解释他们缺少的概念。为什么你永远不应该在用户界面线程上睡觉?这是什么意思?什么是正确的方式呢?@Gray:也许我们应该进入聊天,但是,我不想再光顾程序员了,我希望程序员永远不要再睡UI线程了。我不指望这个答案会被接受,但我相信它的合法性。+1感谢你在工作中使用更好的工具,而不是滥用睡眠-一个没有解释的代码转储。谢谢大家的回答。这真的帮了我很大的忙。现在它的工作方式正是我想要的。