我的活动开始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()
通过意图将其发送到服务。
我想跟踪来自服务的消息。传入的消息正常工作。我需要找到一种方法来正确接收来自活动的消息,执行它们,然后将信息发送回活动。
答案 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的应用程序中测试这些项目。