我正在尝试创建一个简单的多人游戏。有一个WorkerService
应该处理所有网络通信,这个服务和我的活动之间的所有交互都是用AIDL完成的。我认为这是一种标准方法 - 启用双向交互我也使用IWorkerCallback
接口(也是AIDL)。
问题是回调必须在UI中改变,这可能只在UI线程中完成。我创建了一个Handler
(在UI线程中),并认为这是一个明显的解决方案。但是,令人惊讶的是,它没有用。
我的LoungeActivity
调用startServer()
接口的IWorker
方法。我的WorkerService
的相应方法做了一些工作并进行回调 - 这很好。然后WorkerService
产生一个新线程,并且从该线程回调会导致抛出错误的异常:
Can't create handler inside thread that has not called 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,更改Text等)。
我不知道为什么抛出这个异常...我已经设法通过将代码打包到Runnable
并调用runOnUiThread()
来修复它但它仍然让我感到好奇 - 不应该是一个处理程序总是在创建它的线程中运行?或者也许我做错了什么?
答案 0 :(得分:1)
我知道这有点晚了 - 但问题是你打电话给dispatchMessage()
。
正确的方法是sendMessage()
。
dispatchMessage()
会在同一个帖子上调用handleMessage()
。
我猜这个问题不是你的处理程序在错误的线程上 - 但是UI试图在你的onHandle()方法中创建一个Handler。因为在错误的线程上调用了onHandle(),所以会出现异常。
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg)
{
if (msg.callback != null) {
handleCallback(msg);
} else {
handleMessage(msg);
}
}
答案 1 :(得分:0)
你必须以某种方式从主线程调用违规函数。
答案 2 :(得分:0)
更改UI的功能应该在拥有UI的活动中。
此链接可以帮助您: http://android-developers.blogspot.com/2009/05/painless-threading.html