我有一个后台服务,它运行在它自己独立的进程中,使用
android:process=":deamon"在服务的清单条目中。我想从我的活动中与服务(远程进程)进行通信,并从它接收数据。我是通过向远程进程发送消息和从远程进程发送消息来做到这一点的,正如http://developer.android.com/guide/components/bound-services.html#Messenger中所描述的,并且按照他们的建议,我遵循
如果您希望服务响应,那么您还需要在客户机中创建一个Messenger。>然后,当客户机接收到onServiceConnected()回调时,它向>服务发送一条消息,该>服务在send()方法的replyTo参数中包含客户端的Messenger。
问题是,我需要提供一个阻塞/同步API来从远程服务中获取数据,我的" get“函数如何阻止调用方,然后返回传入Handler中接收到的数据?做这件事的最佳方法是什么?
发布于 2015-04-23 13:01:38
这是客户端消息传递部分的代码。
SparseArray<CountDownLatch> lockArray = new SparseArray<>();
SparseArray<Bundle> msgDataArray = new SparseArray<>();
public Bundle sendAndWaitResponse(Message msg) throws
RemoteException, InterruptedException {
int msgId = msg.arg2;
Log.d("PlatformConnector", "Sending message to service, Type: "
+ msg.what + ", msgId: " + msg.arg2);
CountDownLatch latch = new CountDownLatch(1);
lockArray.put(msgId, latch);
platformMessenger.send(msg);
latch.await();
Bundle response = msgDataArray.get(msgId);
lockArray.delete(msgId);
msgDataArray.delete(msgId);
return response;
}
void storeResponseAndNotify(Message msg) {
int msgId = msg.arg2;
// Because the message itself is recycled after Handler returns,
// we should store only the data of message
msgDataArray.put(msgId, msg.getData());
lockArray.get(msgId).countDown();
}
private class ClientMessageHandler extends Handler {
@Override
public void handleMessage(Message msg) {
storeResponseAndNotify(msg);
}
}这是使用上述代码的示例。RandomInt.getNextInt()是我自定义的静态方法,它用Random.nextInt()生成随机整数。
public JSONObject doSomething(JSONObject object) {
Message msg = Message.obtain(null, Constants.MESSAGE_SOMETHING, 0, RandomInt.getNextInt());
Bundle bundle = new Bundle();
bundle.putString(Constants.MESSAGE_DATA_SOMETHING, object.toString());
msg.setData(bundle);
try {
Bundle responseData = sendAndWaitResponse(msg);
return new JSONObject(responseData.getString(Constants.MESSAGE_DATA_RETURN));
} catch (RemoteException e) {
Log.e(TAG, "Failed to send message to platform");
e.printStackTrace();
} catch (InterruptedException e) {
Log.e(TAG, "Interrupted while waiting message from platform");
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}顺序如下,
Message并将其arg2设置为一些随机整数(此整数将是用于同步的消息id )。CountDownLatch并将其放到LockArray中。sendAndWaitResponse()发送消息。它通过Messenger向服务发送消息,并调用latch.await()。arg2应该与接收到的消息相同。Messenger在replyTo中向客户端发送回复消息。storeResponseAndNotify处理消息。msgDataArray中准备好。CountDownLatch是用来阻塞和解除阻塞线程的简单开关。(http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html)
SparseArray类似于HashMap,但对于较小的集合则更节省内存。(http://developer.android.com/reference/android/util/SparseArray.html)
小心不要阻塞Messenger的线程。Messenger在单个线程中运行,如果从handleMessage()阻塞,它将阻塞所有其他消息并导致脱锁问题。
https://stackoverflow.com/questions/25790854
复制相似问题