我正在尝试创建一个简单的多人游戏。有一个 WorkerService
应该处理所有网络通信,并且此服务与我的 Activity 之间的所有交互都是使用 AIDL 完成的。我认为这是一种标准方法 - 为了实现双向交互,我还使用了一个 IWorkerCallback
接口(interface)(也是 AIDL)。
问题是回调必须改变 UI 中的东西,而这只能在 UI 线程中完成。我创建了一个 Handler
(在 UI 线程中)并相信这是一个显而易见的解决方案。但是,令人惊讶的是,它不起作用。
我的LoungeActivity
调用IWorker
接口(interface)的startServer()
方法。我的 WorkerService
的相应方法做了一些工作并进行了回调 - 这工作正常。然后 WorkerService
生成一个新线程,并且从这个线程回调导致抛出错误的异常:
无法在尚未调用 Looper.prepare() 的线程内创建处理程序
这里有一些代码来说明:
startServer()
实现:
private void startServerImpl(String name, float latStart, float latEnd,
float lonStart, float lonEnd)
{
// some instructions here
// this works fine:
callback.notifySocketCreated();
// my naughty thread:
new ServerThread().start();
// some instructions here
}
ServerThread
代码:
private class ServerThread extends Thread {
@Override
public void run()
{
//some instructions here
// this call will cause an error
callback.notifyGameRegistered();
}
}
callback
中的每个方法看起来都是这样的:
public void notifyGameRegistered() throws RemoteException
{
handler.dispatchMessage(handler.obtainMessage(CALLBACK_GAME_REGISTERED));
}
在 Handler 的 handleMessage()
方法中,我正在做一个简单的 switch(msg.what)
并且在每种情况下都有一个简单的 UI 修改(显示 Toast,更改文本等)。
我不知道为什么会抛出这个异常。我已经设法通过将代码打包到 Runnable
并调用 runOnUiThread()
来修复它,但它仍然使我很好奇 - 处理程序不应该总是在创建它的线程中运行吗?还是我做错了什么?
最佳答案
我知道这有点晚了 - 但问题是你调用了 dispatchMessage()
。
正确的方法是sendMessage()
。
dispatchMessage()
将在同一线程上调用 handleMessage()
。
我猜问题不在于您的 Handler 在错误的线程上 - 而是 UI 试图在您的 onHandle() 方法中的某处创建一个 Handler。因为在错误的线程上调用了 onHandle(),所以会出现异常。
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg)
{
if (msg.callback != null) {
handleCallback(msg);
} else {
handleMessage(msg);
}
}
关于android - 来自另一个线程的回调导致异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2769297/