【问题标题】:use thread to wait for message from service使用线程等待来自服务的消息
【发布时间】:2014-07-10 17:11:23
【问题描述】:

我有一个绑定的服务,我向它发送消息,它会将消息发回。所有这些都发生在另一个名为 DataItems 的类中。

主要活动使用此方法调用 DataItems:

DataItems.getItems();

DataItems 将向请求项目的服务发送一条消息,当它收到返回的消息时(通过处理程序,它应该将它发送回调用活动)。

Items results = null;

public Items getItems() {
    sendMessage(); // sends a message to service;
    boolean messageNotReceived = true;
    --> while(messageNotReceived); // wait for message to come back;
    return results;
}


private class CustomHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
            results = msg.getData().getParcelable("items");
            messageNotReceived = true;
    }
}

问题是while循环会阻塞线程,直到while循环完成,handleMessage方法才会被调用。我认为其中一个必须在单独的线程中运行,以保持另一个畅通。

如果我在单独的线程中运行 getItems(),它将如何将结果返回给调用活动?

getItems() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(messageNotReceived);
            // how to return value from here???
        }
    }
    // any operation here will continue in parallel with the thread
    // so any return statements here will be returned to the activity.
}

那么问题是如何在不阻塞整个执行线程的情况下等待来自Service的消息?

【问题讨论】:

  • 为什么在收到消息的处理程序中收到消息后不做你需要做的事情?
  • 因为不同消息的场景不同。而且它在一个库模块中,所以我需要将数据传递给活动,而不是将所有案例都放在handleMessage中,这在此处是不可能的。
  • 为什么不在有 doInBackground() 和 onPsotExecute() 的地方使用 AsyncTask。您可能知道 onPostExecute() 将在 doInBackground() 完成后执行。

标签: android multithreading thread-safety handler


【解决方案1】:

在这种情况下,我建议您在Activity 中使用BroadcastReceiver。每当handleMessage结束时,发送Broadcast到你的Activity,然后你就可以调用DataItems.getItems();

【讨论】:

    【解决方案2】:

    考虑在您的handleMessage() 方法中包含一个案例,用于检查您收到的消息类型。例如:

    @Override
    public void handleMessage(Message msg) {
            if (msg.getData().getString("sender", "").equals("senderA") {
                  // Handle message of type A
            }
            else if (msg.getData().getString("sender", "").equals("senderB") {
                  // Handle message of type b
            }
            // ...
    }
    

    这样,您的 DataItems 线程就不必在等待响应时连续运行。相反,它将在正确的时间由一条消息启动。

    【讨论】:

    • 这如何将数据返回给调用 Data.getItems() 的活动?我认为您建议我在每个活动中实现一个处理程序来处理消息。我正在避免这种情况,因为处理程序部分位于库中的活动之外。
    • @kicker86 我明白了,我似乎误读了您的问题,询问如何在服务完成运行时通知 DataItems。在这种情况下,我建议消除 while 循环,并按照 Kingfisher 的建议执行以下操作:void getItems() {sendMessage();}(无需返回)和handleMessage() {// Send broadcast...}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2020-09-18
    • 2021-03-09
    • 2022-06-16
    • 1970-01-01
    相关资源
    最近更新 更多