1

我有一个活动开始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);
}

我使用 aBroadcastReceiver从服务接收消息:

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 卡住了。我尝试使用 anAsyncTask但它没有用。我认为我需要停止使用该静态write()方法并将消息发送到服务并让他完成这项工作。我相信我需要Handler在活动中初始化 a ,通过意图将其发送到服务startService()

我想跟踪进出服务的消息。它可以很好地处理传入的消息。我需要找到一种方法来正确接收来自活动的消息,执行它们,然后将信息发送回活动。

4

1 回答 1

3

首先,关于IntentService

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

因此,请考虑将您的代码移动到Service. 我不确定蓝牙连接和NetworkOnMainThreadException,但以防万一:请注意 aService在主 UI 线程上运行,因此为避免此类异常,您将需要Thread在服务中使用类似的东西。不要使用AsyncTask,因为理想情况下 AsyncTasks 应该用于短操作(最多几秒钟)。还要注意系统将自动管理服务的生命周期,你不应该/不能在任何静态方法中与它交互。

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

并且要将消息从活动发送到服务,我假设您已移至Service. 您可以将任何内容放入一个IntentstartService()再次调用以发送它。您将在onStartCommand(). 或者,如果您使用此技术绑定了服务,则可以直接从活动内部调用服务的方法。

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

于 2013-03-13T09:33:13.333 回答