来自另一个线程的回调会导致异常

时间:2010-05-04 22:09:42

标签: android multithreading service aidl

我正在尝试创建一个简单的多人游戏。有一个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()来修复它但它仍然让我感到好奇 - 不应该是一个处理程序总是在创建它的线程中运行?或者也许我做错了什么?

3 个答案:

答案 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