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

标签 android multithreading service aidl

我正在尝试创建一个简单的多人游戏。有一个 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/

相关文章:

java - android.view.InflateException : Binary XML file line #9 error inflating class com. hamweather.aeris.maps.AerisMapView

java - 多线程环境中缓存集合的无限循环

c++ - 在不锁定的情况下在线程之间复制 std::vector

security - 如何使软件安全变得真正简单?

Android onTaskRemoved() 调用网络服务

java - 将 equinox OSGi 作为 Fedora 服务运行

android - Android 代码示例入门 - 权限错误

android - 如何在 Android 中扩展 TableLayout 的中间 TableRow?

Android:如何在特定时间内停止播放媒体(mp3)?

python - 使用curses,如何更新屏幕或等待按键?