如何在服务运行时将消息从活动发送到服务并执行它们?

时间:2013-03-12 09:51:31

标签: android service android-activity handler intentservice

我的活动开始IntentService

intent = new Intent(MyApplication.getAppContext(), MyService.class);
intent.putExtra("EXTRA_DEVICE_ADDRESS", value);
MyApplication.getAppContext().startService(intent);

该服务使用我发送的MAC地址启动蓝牙连接。

device = mBluetoothAdapter.getRemoteDevice(macAddress);

public ConnectThread(BluetoothDevice device) {
    this.mmDevice = device;
    BluetoothSocket tmp = null;
    try {
        tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));
    } catch (IOException e) {
        e.printStackTrace();
    }
    mmSocket = tmp;
}

我听着:

while (true) {
    try {
        if (mmInStream.available() != 0) {
            bytes = mmInStream.read(buffer);    
            String readMessage = new String(buffer, 0, bytes);
            sendMessageToActivity("incoming", readMessage);
        } else {
            SystemClock.sleep(100);
        }

并将收到的消息发送回活动:

public void sendMessageToActivity(String type, String message) {
    intent = new Intent(BROADCAST_ACTION);
    intent.putExtra(type, message);
    sendBroadcast(intent);
}

我使用BroadcastReceiver接收来自服务的消息:

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        updateUI(intent);
    }
};

我从问题的活动( 部分 )致电:

private void writeOut(final String message) {
    msg = message;
    byte[] send = msg.getBytes();
    MyService.write(send);
}

这是服务的静态write()方法:

public static void write(byte[] out) {
    // Create temporary object
    ConnectedThread r;
    // Synchronize a copy of the ConnectedThread
    synchronized (obj) {
        if (mState != STATE_CONNECTED)
            return;
        r = mConnectedThread;
    }
    // Perform the write unsynchronized
    r.write(out);`
}

我的问题:除了MyService.write(send)之外,上述所有工作都按预期进行。 UI卡住了。我尝试使用AsyncTask,但它没有用。我想我需要停止使用静态write()方法并向服务发送消息并让他完成工作。我相信我需要在活动中初始化Handler,通过startService()通过意图将其发送到服务。

我想跟踪来自服务的消息。传入的消息正常工作。我需要找到一种方法来正确接收来自活动的消息,执行它们,然后将信息发送回活动。

1 个答案:

答案 0 :(得分:3)

首先,关于IntentService

  

所有请求都在一个工作线程上处理 - 它们可能需要多长时间(并且不会阻止应用程序的主循环),但只有 一个 请求将一次处理。

因此,请考虑将代码移至Service。我不确定蓝牙连接和NetworkOnMainThreadException,但为了以下情况:请注意Service在主UI线程上运行,所以为了避免这种异常,你需要像{{1}这样的东西。在你的服务中。不要使用AsyncTask,因为 AsyncTasks理想情况下应该用于短操作(最多几秒钟。)还要注意系统将自动管理服务的生命周期,你不应该 / 无法在任何静态方法中与进行交互。

现在回到你的问题。您使用广播接收器(将消息从服​​务发送到活动)的方式是正确的,但请考虑使用ResultReceiver(API 3+中提供)。我认为,使用Thread比发送广播消息更好。您可以将ResultReceiver放入ResultReceiver

要将活动中的消息发送到服务,我假设您已转移到Intent。您可以将任何内容放入Service并再次致电Intent发送。您将获得onStartCommand()中的意图。或者,如果您使用this technique绑定了服务,则可以从活动内部直接调用服务的方法

有一些示例项目在SDK中使用服务 - 文件夹startService()。在模拟器上,您可以在名为API Demos的应用程序中测试这些项目。