我有一个耗时的任务(迭代文件并将其内容发送到服务器)我想在后台线程中执行,在特定的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
开始一个新线程?我也在我的应用程序的其他部分使用处理程序,它们工作得很好。我做错了吗?
答案 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是一个很好的解决方案。