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

2023-09-12 23:44:18 作者:早无谓i

我有开始活动的 IntentService

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

在服务启动的MAC地址我送一个蓝牙连接。

The service starts a Bluetooth connection with the MAC address I sent.

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);
        }

和发送接收到的消息回活动:

And send received messages back to the activity:

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);
    }
};

我从活动的调用( 部分的的问题):

I call from the activity (part of the problem):

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

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

This is the service's static write() method:

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(发送)。用户界面卡。我试图用一个的AsyncTask ,但没有奏效。我想我需要停止使用静态的write()方法和发送信息到服务,让他做的工作。我相信我需要初始化一个处理程序的活动,它通过发送到由目的服务startService()

My problem: All of the above works as intended except MyService.write(send). UI gets stuck. I tried to use an AsyncTask but it didn't work. I think I need to stop using that static write() method and send messages to the service and let him do the job. I believe I need to initialize a Handler in the activity, send it to the service by the intent via startService().

我想跟踪并从该服务的消息。这是工作的罚款与进来的消息。我需要找出一种方法来正确地从活动接收消息,执行它们,然后将信息发回的活动。

I want to keep track of the messages in and out from the service. It is working fine with incoming messages. I need to figure out a way to properly receive messages from the activity, execute them and then send information back to the activity.

推荐答案

首先,有关的 IntentService

First, about IntentService:

所有的请求都在一个单一的工作线程处理 - 他们可能只要必要时采取(并不会阻止应用程序的主循环),但只的的一个的请求将在一个时间被处理。

All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.

所以,考虑将你的code到 服务 。我不知道蓝牙连接和 NetworkOnMainThreadException ,但以防万一:注意,服务运行在主UI线程,因此要避免这样的异常,则需要像服务里。不要使用 的AsyncTask < /一>,因为 AsyncTasks理论上应该用于短操作(几秒钟之最。)的另请注意,系统将自动管理服务的生命周期,你的不应该 / 不能的用它在任何静态方法进行交互。

So, consider moving your code to a Service. I'm not sure about Bluetooth connections and NetworkOnMainThreadException, but just in case: note that a Service runs on main UI thread, so to avoid of such exception, you will need something like Thread inside your service. Don't use AsyncTask, because AsyncTasks should ideally be used for short operations (a few seconds at the most.) Also note that the system will manage the service's lifecycle automatically, you shouldn't/ cannot interact with it in any static methods.

现在回到你的问题。你用广播接收器(从服务到活动中发送消息)的方式是正确的,但可以考虑使用的 ResultReceiver 资讯(API可用3+)。使用 ResultReceiver 是不是发送范围的广播消息更好,我想。你可以把一个 ResultReceiver 意图

Now come back to your problem. The way you use broadcast receiver (to send messages from the service to the activity) is correct, but consider using ResultReceiver (available in API 3+). Using ResultReceiver is better than sending a wide broadcast message, I think. You can put a ResultReceiver into an Intent.

和从该活动将消息发送到服务,我想你搬到服务。你可以将任何东西放入一个意图并调用 startService()再次发送。你会得到的意图 onStartCommand() 。或者,如果您已绑定使用这种技术的服务,您可以致电服务的方法的直接的从活动中。

And to send messages from the activity to the service, I assume you moved to Service. You can put anything into an Intent and call startService() again to send it. You'll get the intent in onStartCommand(). Or if you have bound the service using this technique, you could call the service's methods directly from inside the activity.

有一些样本项目中的SDK服务工作 - 文件夹 [Android SDK中] /样本/ 。在仿真器,你可以在应用程序命名的API演示测试的项目。

There are some sample projects working with services in the SDK — folder [Android SDK]/samples/. On emulators, you can test those projects in the app named API Demos.