2

我有一个非常简单的活动,可以将自定义日期时间字符串打印到 textView。我在它自己的 MainActivity 中实现了一个可运行的接口,并在方法Thread的末尾创建了一个onCreate

Thread thread = new Thread(this);
thread.run();

这是运行方法

public void run() {

        while (true) {
            try {
                Thread.sleep(1000);
                localTime.setText(LocalTime.getTime().format2445());
                System.out.println(LocalTime.getTime().format2445());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    } 

当我在模拟器上运行它时,我可以在 logcat 中看到系统。但模拟器在大约 5 秒后显示 ANR。我究竟做错了什么。这种方法不合适吗?是异步任务是去这里的方式吗?我需要每秒更新一次时钟,所以让 AsyncTask 永远运行是一种可以接受的模式吗?

4

5 回答 5

3

我需要每秒更新一次时钟,所以让 AsyncTask 永远运行是一种可以接受的模式吗?

不,不建议这样做。根据AsyncTask Documentation,这些应该只运行很短的时间。我建议您为此使用TimerTimerTask

Timer timer;

public void onStart() {

    timer = new Timer();

    //this will update each second
    timer.scheduleAtFixedRate(new UpdateTask(), 0,1000);
}

class UpdateTask extends TimerTask {
    public void run() {
        //update TextView
    }
}

public void onStop(){

    timer.cancel();
}
于 2013-07-31T14:49:57.217 回答
2

您需要启动thread.start()

http://developer.android.com/reference/java/lang/Thread.html

从文档中引用

有两种方法可以在新线程中执行代码。您可以继承 Thread 并覆盖其 run() 方法,或者构造一个新 Thread 并将 Runnable 传递给构造函数。无论哪种情况,都必须调用 start() 方法才能实际执行新线程。.

你在打电话thread.run()。你也叫 sleep 。你不应该阻塞 ui 线程。

http://developer.android.com/training/articles/perf-anr.html

如果您正在寻找倒数计时器

http://developer.android.com/reference/android/os/CountDownTimer.html

以分和秒为单位的倒计时

您还可以使用 Handler,计时器任务。如果您使用计时器任务,请确保您在 ui 线程上更新 ui。

用于计时器的 Android 线程

编辑:我没有注意到这一点。所以从上面的评论。DoctorDrive 的学分

    localTime.setText(LocalTime.getTime().format2445()); // update ui from thread is not possible

你需要使用runOnUiThread

    runOnUiThread(new Runnable() //run on ui thread
             {
              public void run() 
              { 
                localTime.setText(LocalTime.getTime().format2445());

              }
             });
于 2013-07-31T14:51:51.093 回答
2

尝试这样的事情。

new Thread(new Runnable() {
public void run() {
  Thread.sleep(1000);
  localTime.setText(LocalTime.getTime().format2445());
  System.out.println(LocalTime.getTime().format2445());
}
}).start();
于 2013-07-31T14:49:02.843 回答
2

可能你需要使用 thread.start() 而不是 thread.run()

thread.start 创建一个新线程并在新线程中运行您的代码。

thread.run 在父线程中运行您的代码,不会创建新线程

于 2013-07-31T14:49:26.510 回答
2

这是因为您在 UI 线程中调用 sleep 。永远不要在 UI 线程中调用 sleep 。您可以使用 Handler 在 UI 线程上运行东西。

private static final Handler handler = new Handler();

@Override
protected void onCreate(Bundle state) {
    super.onCreate(state);
    handler.postDelayed(textRunnable, 1000);
}

private final Runnable textRunnable = new Runnable() {
    @Override
    public void run() {
        localTime.setText(LocalTime.getTime().format2445());
        System.out.println(LocalTime.getTime().format2445());
    }
}

或者你可以做到这一点,但不好的方式

@Override
protected void onCreate(Bundle state) {
    super.onCreate(state);
    new Thread() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                System.out.println(LocalTime.getTime().format2445());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        localTime.setText(LocalTime.getTime().format2445());
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }.start();
}
于 2013-07-31T14:51:39.117 回答