从后台处理程序线程传递处理程序到后台线程
任何人都可以在此向我指出正确的方向吗?从后台处理程序线程传递处理程序到后台线程
我有派生两个线程的活动,处理邮件,用活套
public static class MiddleThread extends Handler{
static public Handler handler;
public void run() {
Looper.prepare();
Log.d("MiddleThread", "Looper is prepared !");
handler = new Handler() {
public void handleMessage(Message msg)
{
Bundle bundle = msg.getData();
String exitString = bundle.getString("endmessage");
if(exitString.equals(("ExitOK")))
{
boolean searchFinished = true;
Looper looper = Looper.myLooper();
looper.quit();
} else
{
int fileCount = bundle.getInt("filecount");
String fileName = bundle.getString("filename");
Log.d("MiddleThread", "File Number " + fileCount + " is " + fileName);
}
}
};
Log.d("MiddleThread", "nandler should be initialised");
Looper.loop();
}
线程...那么它产生的主要工作线程,它是从UI线程通过处理程序,和来自上述线程的处理程序。
public class BasicSearch {
public Handler handlerUi, handlerMiddleThread;
public Message messageUi, messageMiddleThread;
public int fileCount = 0;
public BasicSearch(Handler ui, Handler mt) {
handlerUi = ui;
handlerMiddleThread = mt;
}
public void listFiles()
{
File searchPath = Environment.getExternalStorageDirectory();
messageUi = handlerUi.obtainMessage();
messageMiddleThread = handlerMiddleThread.obtainMessage();
walk(searchPath);
Bundle b = new Bundle();
b.putString("endmessage", "ExitOK");
messageMiddleThread.setData(b);
handlerMiddleThread.dispatchMessage(messageMiddleThread);
}
private void walk(File path) {
File[] list = path.listFiles();
for(File f : list)
{
if(f.isDirectory())
{
walk(new File(f.getAbsolutePath()));
} else {
processFile(f);
}
}
}
private void processFile(File f) {
Bundle b = new Bundle();
fileCount++;
b.putString("filename", f.getName());
b.putInt("filecount", fileCount);
messageMiddleThread.setData(b);
Log.d("BasicSearch", "Data is set, to send to MiddleThread");
handlerMiddleThread.dispatchMessage(messageMiddleThread);
Log.d("BasicSearch", "Message sent");
}
}
无论发生什么事,当它试图在DispatchMessage,handlerMiddleThread恢复到被空。我甚至在我的活动中有下面的代码,试图确保它不是null,但是当我发送消息时它仍然最终为null。
startMiddleThread();
while(true)
{
if(MiddleThread.handler != null)
break;
}
startSearchThread();
这是一个测试项目,因为我希望能够在继续使用我的项目之前正确理解Handler/Looper概念。
我已经成功设法在我的UI线程中使用了一个处理程序,但是我的当前项目在UI中进行的处理过多,我想要一个辅助线程处理searchThread的输出,并且只接收线程完成时UI线程中的消息。
所以我想我看到你正在试图做的,让我提出一个稍微简单的方法是什么:
要启动后台线程,并获得处理它:
HandlerThread bgThread = new HandlerThread();
bgThread.start();
Handler bgHandler = new Handler(bgThread.getLooper());
然后你可以发送你想要的任何消息给你的bgHandler。请注意,您需要在创建bgThread之前调用HandlerThread的start(否则getLooper()将返回null)。
这就是说,我想我知道你的代码发布了什么错误。首先,MiddleThread扩展了Handler(它没有run()方法!)而不是Thread。其次,MiddleThread上的run()方法永远不会被调用,所以Handler永远不会被实例化。即使你在上面的代码中错误地输入了Handler,并且你实际上在扩展Thread,你仍然需要在MiddleThread上调用start,以便执行run()中的任何内容。实际上,你所做的事情就是,它需要变得更加复杂,而且你几乎可以肯定地只是做我上面提到的。
感谢Monkeyless。我把它放回线程,它实际上不需要start()方法。 run()中的代码在LogCat中没有执行,由log.d输出确认。我稍后会测试你的建议,但你说得对,我可能过于复杂。我想要做的事情都可以在一个线程中完成,而UI只是通过一个处理程序被告知它已完成。尽管如此,我只想纯粹使用处理程序来处理后台处理。 –
啊,没有使用处理程序进行后台处理是完全正确的,这正是我的例子所做的。任何通过bgHandler.post(new Runnable()...)传递的runnable将在后台线程上执行。我的意思是,为了创建和使用后台线程,您不需要扩展线程或自己创建/调用一个Looper。相反,您可以像我所示的那样使用HandlerThread,它可以为您处理所有这些事情。 –
将您的活动代码与您称为'run'和'new BasicSearch'的代码一起发布。 – njzk2