如何在Android中暂停/休眠线程或进程?

我想在两行代码之间停顿一下,让我解释一下:

– >用户点击一个按钮(实际上是一个卡),我通过改变这个按钮的背景来显示它:

thisbutton.setBackgroundResource(R.drawable.icon); 

– >让我们说1秒后,我需要通过改回其背景回到按钮的前一个状态:

 thisbutton.setBackgroundResource(R.drawable.defaultcard); 

– >我试着暂停这两行代码之间的线程:

 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

但是,这是行不通的。 也许这是过程,而不是我需要暂停的线程?

我也试过(但不起作用):

 new Reminder(5); 

有了这个:

 public class Reminder { Timer timer; public Reminder(int seconds) { timer = new Timer(); timer.schedule(new RemindTask(), seconds*1000); } class RemindTask extends TimerTask { public void run() { System.out.format("Time's up!%n"); timer.cancel(); //Terminate the timer thread } } } 

我怎样才能暂停/休眠线程或进程?

解决这个问题的一个办法是使用Handler.postDelayed()方法。 一些Google 培训材料提出了相同的解决方案。

 @Override public void onClick(View v) { my_button.setBackgroundResource(R.drawable.icon); Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { my_button.setBackgroundResource(R.drawable.defaultcard); } }, 2000); } 

然而,有人指出,下面的解决方案会导致内存泄漏,因为它使用了一个非静态的内部和匿名类,隐式地持有对它的外部类(活动)的引用。 当活动上下文被垃圾收集时,这是一个问题。

避免内存泄漏的更复杂的解决方案将HandlerRunnable分类为活动内部的静态内部类,因为静态内部类不包含对其外部类的隐式引用:

 private static class MyHandler extends Handler {} private final MyHandler mHandler = new MyHandler(); public static class MyRunnable implements Runnable { private final WeakReference<Activity> mActivity; public MyRunnable(Activity activity) { mActivity = new WeakReference<>(activity); } @Override public void run() { Activity activity = mActivity.get(); if (activity != null) { Button btn = (Button) activity.findViewById(R.id.button); btn.setBackgroundResource(R.drawable.defaultcard); } } } private MyRunnable mRunnable = new MyRunnable(this); public void onClick(View view) { my_button.setBackgroundResource(R.drawable.icon); // Execute the Runnable in 2 seconds mHandler.postDelayed(mRunnable, 2000); } 

请注意, Runnable对活动使用WeakReference ,这在需要访问UI的静态类中是必需的。

你可以尝试这个

 SystemClock.sleep(7000); 

警告 :永远不要在UI线程上这样做。

用这个睡觉,例如。 背景线程。


您的问题的完整解决方案将是:这是可用的API 1

 findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View button) { button.setBackgroundResource(R.drawable.avatar_dead); final long changeTime = 1000L; button.postDelayed(new Runnable() { @Override public void run() { button.setBackgroundResource(R.drawable.avatar_small); } }, changeTime); } }); 

没有创建tmp处理程序。 这个解决方案比@tronman更好,因为我们不保留Handler的视图。 此外,我们没有处理程序创建坏线程的问题;)

文档

public static void sleep(long ms)

在API级别1中添加

在返回之前等待给定的毫秒数(uptimeMillis)。 类似于sleep(long), 但不抛出InterruptedException ; 中断()事件被推迟到下一个可中断操作。 直到至少达到指定的毫秒数才会返回

参数

ms在返回之前休眠,正常运行时间以毫秒为单位。

来自View类的postDelayed代码:

 /** * <p>Causes the Runnable to be added to the message queue, to be run * after the specified amount of time elapses. * The runnable will be run on the user interface thread.</p> * * @param action The Runnable that will be executed. * @param delayMillis The delay (in milliseconds) until the Runnable * will be executed. * * @return true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. Note that a * result of true does not mean the Runnable will be processed -- * if the looper is quit before the delivery time of the message * occurs then the message will be dropped. * * @see #post * @see #removeCallbacks */ public boolean postDelayed(Runnable action, long delayMillis) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.postDelayed(action, delayMillis); } // Assume that post will succeed later ViewRootImpl.getRunQueue().postDelayed(action, delayMillis); return true; } 

我使用这个:

 Thread closeActivity = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); // Do some stuff } catch (Exception e) { e.getLocalizedMessage(); } } }); 

你可能不想这样做。 通过在你的按钮点击的事件处理程序中放入一个明确的sleep() ,你实际上会锁定整个UI一秒钟。 另一种方法是使用某种单次计时器 。 创建一个TimerTask将背景颜色更改为默认颜色,并将其安排在Timer上。

另一种可能是使用Handler 。 有一个关于从使用定时器切换到使用处理程序的人的教程 。

顺便说一句,你不能暂停一个进程。 Java(或Android)进程至少有一个线程,并且只能休眠线程。

这是我在一天结束时所做的 – 现在正常工作:

 @Override public void onClick(View v) { my_button.setBackgroundResource(R.drawable.icon); // SLEEP 2 SECONDS HERE ... final Handler handler = new Handler(); Timer t = new Timer(); t.schedule(new TimerTask() { public void run() { handler.post(new Runnable() { public void run() { my_button.setBackgroundResource(R.drawable.defaultcard); } }); } }, 2000); } 

除了Yankowsky先生的回答之外,您还可以使用postDelayed() 。 这在任何View (例如,你的卡)上都可用,并且需要一个Runnable和一个延迟期。 它在延迟之后执行Runnable

我使用CountDownTime

 new CountDownTimer(5000, 1000) { @Override public void onTick(long millisUntilFinished) { // do something after 1s } @Override public void onFinish() { // do something end times 5s } }.start(); 

这是我的例子

创建一个Java Utils

  import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; public class Utils { public static void showDummyWaitingDialog(final Context context, final Intent startingIntent) { // ... final ProgressDialog progressDialog = ProgressDialog.show(context, "Please wait...", "Loading data ...", true); new Thread() { public void run() { try{ // Do some work here sleep(5000); } catch (Exception e) { } // start next intent new Thread() { public void run() { // Dismiss the Dialog progressDialog.dismiss(); // start selected activity if ( startingIntent != null) context.startActivity(startingIntent); } }.start(); } }.start(); } }