与线程混淆 - 处理程序阻止UI线程

时间:2011-08-08 07:43:30

标签: android multithreading

我有一个耗时的任务(迭代文件并将其内容发送到服务器)我想在后台线程中执行,在特定的interwal中(这就是我想使用Handler的原因)。

从UI线程我有这样的调用:

LogsManager lm;
lm = new LogsManager(this);
lm.processLogFiles();

LogsManager课程中,我有以下代码:

public void processLogFiles(){
    Handler mHandler = new Handler();
    mHandler.postDelayed(logsRunable, 1000);    
}

private Runnable logsRunable = new Runnable() {
        @Override
        public void run() {
            File f = new File(Environment.getExternalStorageDirectory()+Constants.LOG_DIR);             
            File[] logFiles = f.listFiles();
            for (int i = 0; i < logFiles.length; i++) {
                readLogs(logFiles[i]); // executes some other methods inside
            }
        }
    };

正如您所看到的那样只是调用Handler Runnable的方法。不幸的是,它也阻止了我的UI线程。是不是Handler应该为Runnable开始一个新线程?我也在我的应用程序的其他部分使用处理程序,它们工作得很好。我做错了吗?

4 个答案:

答案 0 :(得分:10)

the docs中所述,Handler

  

当你创建一个新的Handler时,它被绑定到创建它的线程的线程/消息队列

因此,如果您在UI线程中创建mHandler,那么它将在UI线程中运行任务 - 因此出现问题。

答案 1 :(得分:3)

Handler中的所有post *方法都在Handler的原始线程上运行代码(在您的情况下是GUI线程)。如果你想要一个后台线程,你需要显式启动它(见下文)或使用AsyncTask,如果你需要更新GUI。

Thread t = new Thread(logsRunable);
t.start();

答案 2 :(得分:0)

我认为您应该为此目的使用AsyncTask类。

在特定延迟后计划执行任务,在您的情况下为1000.

答案 3 :(得分:0)

我也认为AsyncTask是一个很好的解决方案。