小编典典

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

all

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

-> 用户单击一个按钮(实际上是一张卡片),我通过更改此按钮的背景来显示它:

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
            }
        }  
    }

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


阅读 69

收藏
2022-04-15

共1个答案

小编典典

此问题的一种解决方案是使用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使用了对 Activity
WeakReference,这在需要访问
UI 的静态类中是必需的。

2022-04-15