在长线程过程中更新TextView

时间:2012-09-30 16:30:12

标签: android multithreading

为了清楚起见,这个问题不是关于如何从线程更新TextView,这工作正常。问题是即使我在整个线程中进行多次调用来更新TextView,更新只会在Thread完成后才会出现。这是一个例子:

public class NDThread extends Thread {

    protected LogActionListener log_listener;
    private Handler handler = new Handler();


    public void run() {
        logAction("starting");
        // Do many things..
        logAction("halfway");
        // Many more things..
        logAction("done");
    }

    public interface LogActionListener {
        public void onLogAction(String paramString);
    }

    public void logAction(final String str) {
        if(log_listener != null) handler.post(new Runnable() {
            @Override
            public void run() {
                log_listener.onLogAction(str);          
            }       
        });
    }
}

在我的主Activity中,我实现LogActionListener来接收字符串并更新TextView:

NDThread thread = new NDThread();
thread.setOnLogActionListener(this);
thread.run();

// Elsewhere..
@Override
public void onLogAction(final String msg) {
        handler.post(new Runnable() {

            @Override
            public void run() {
                textView.append(msg);
            }

        });
}

正如您所看到的,我在Thread和Activity中都使用了Handler,因为我不确定哪个是正确的。但是,结果始终是整个Thread的空白TextView,然后在最后它将打印3行。我做错了什么?

4 个答案:

答案 0 :(得分:2)

避免线程并前往 AsyncTask

您要找的是AsyncTask的 onProgressUpdate(进度...),publishProgress(进度...)

Google提供代码示例。

答案 1 :(得分:1)

尝试使用runOnUiThread并更新其中的textview

答案 2 :(得分:0)

尝试通过以下方式替换onLogAction()的定义:

@Override
public void onLogAction(final String msg) {
  textView.append(msg);
}

答案 3 :(得分:0)

问题出在这里

NDThread thread = new NDThread();
thread.setOnLogActionListener(this);
thread.run();

应该是

NDThread thread = new NDThread();
thread.setOnLogActionListener(this);
thread.start();

因为“start()方法创建了一个新线程,它执行run()方法。 run()方法只在当前线程中执行,而不启动新线程。“

另外正如其他人所说,你不需要两个处理程序。只是做:

    public void logAction(final String str) {
        if(log_listener != null) log_listener.onLogAction(str);          
    }

并在主要活动中

    @Override
    public void onLogAction(final String msg) {
       MyActivity.this.runOnUiThread( new Runnable() {
          @Override
          public void run() {
           textView.append(msg);
          }
       });
    }