如何安全地停止从alertdialog启动的线程?

时间:2015-02-13 21:46:24

标签: java android multithreading

当我显示alertdialog时,我启动一个开始30秒倒计时的线程来更新此alertdialog中显示的确定进度条。

我将runnable创建为一个静态内部类,这样我就不会泄漏上下文(活动),但当然我无法访问该标志来停止该线程,也不能查看我想要的视图更新。我怎么能绕过这个?

public class MyDialogFragment implements DialogInterface.onShowListener, DialogInterface.onDismissListener {

private boolean stopThread = false;
private Progressbar countdownBar;
private TextView countdownRatio;

@Override public void onShow() { 
    Thread progressThread = new Thread(new myRunnable());
    progressThread.start();
}

@Override public void onDismiss() {
    stopThread = true;
    this.dismiss();
}

private static class myRunnable implements Runnable {

    int progressStatus = 0;
    int numSeconds = 30;

    @Override public void run() {
        while (!threadStop && progressStatus < numSeconds) {
            progressStatus++;

            handler.post(new Runnable() {
                public void run() {
                    countdownBar.setProgress(progressStatus);
                    countdownRatio.setText(progressStatus + "/" + numSeconds + " secs");
                }
            });
            try {
                // update the counter every sec
                Thread.sleep(1000);

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

1 个答案:

答案 0 :(得分:1)

首先 - 不要使用Thread - 您要求解决问题,尤其是您似乎对多线程编程感到满意。这是一个棘手的话题,有很多陷阱。它绝对不适合新手。

您可以使用AsyncTask - 它通过AsyncTask.onProgressUpdate()与UI事件循环很好地集成。 AsyncTask使用内部线程池。

http://developer.android.com/guide/components/processes-and-threads.html#Threads

AsyncTask适用于大多数琐碎的事情。对于更高级的用途,请尝试将Service与工作线程和消息总线一起使用以与片段或活动进行通信。有很多用于异步编程的库。我可以推荐这个:

https://github.com/stephanenicolas/robospice

它是网络的主要目的,但你也可以将它用于其他东西。

第三个解决方案是Loader API:

http://developer.android.com/reference/android/content/Loader.html

它旨在从数据库异步加载数据(SQLite很慢),但它很容易用于其他东西,例如数据处理。

请记住:如果您使用Thread,则有两种可能性:

  1. 你是专家,你知道你在做什么
  2. 你是绿色的,你做错了