Android - sendBroadcast() 和 onReceive() - 进程间通信的同步解决方案
我想创建一个库,以同步方式(从客户端)执行一些意图发送/接收操作。这样我的图书馆的客户就不必关心接收器的实现。
图书馆会将意图发送到某处并接收响应。然后将结果同步返回给客户端。
用例是使用意图在我自己的应用程序之间传输一些数据。通常我异步使用意图和接收器(因为它们应该工作),但这是规则的例外。
建议的解决方案(简化!)。图书馆:
public class Helper {
private Context context;
private BroadcastReceiver tempReceiver;
private int result = 0;
int getResult() {
tempReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Helper.this.result = 1;
}
};
context.registerReceiver(tempReceiver);
context.sendBroadcast(/* ask for smth */);
Thread.sleep(5000);
context.unregisterReceiver(tempReceiver);
return result;
}
}
客户端是一个希望从图书馆获取一些数据的应用程序,例如:
int timeout = 5000;
Helper lib = new Helper(timeout);
lib.getData();
您对此有何看法?有哪些威胁?我知道调用 getReturn() 会阻塞并且无法在 GUI 线程中调用。睡眠解决方案是否可以接受的问题。
I would like make a library that would do some intent send/receive stuff in a synchronous way (from the client side). So that client of my library won't have to care about implementing receivers.
The library would send intent somewhere and receive the response. Then it would return the result to the client synchronously.
The Use case is to transport some data between my own applications using intents. Usually I use intents and receiver asynchronously (as they supposed to work), but this an exception for the rule.
Proposed solution (simplified!). Library:
public class Helper {
private Context context;
private BroadcastReceiver tempReceiver;
private int result = 0;
int getResult() {
tempReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Helper.this.result = 1;
}
};
context.registerReceiver(tempReceiver);
context.sendBroadcast(/* ask for smth */);
Thread.sleep(5000);
context.unregisterReceiver(tempReceiver);
return result;
}
}
The client is an application that would like to get some data from the library, like that:
int timeout = 5000;
Helper lib = new Helper(timeout);
lib.getData();
What do you think about that? What are the threats? I understand that calling getReturn() would be blocking and cannot be called in GUI thread. The question if the sleep solution is acceptable.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为您已经了解标准同步与异步的权衡,以及它们有利和不利的情况。
IMO,只有当广播也由您自己的应用程序发送时,您的方法才可以。如果您对系统广播感兴趣,那么 5 秒的延迟可能在可接受的延迟和灾难性的延迟之间变化。想象一下,注册一个“拍摄照片”广播,然后 5 秒后,当用户拍摄另一张照片时,您的同步调用返回,并显示一些内容,从而让用户烦恼不已。
另外,您建议如何处理广播不是一次性而是连续的情况?
我曾尝试在幕后使用
AsyncTask
设计一个 API;并以同步方式公开它。但事实证明,这个 API 的使用会让客户端代码更加混乱。我的结论是,某些事情并不意味着同步完成;而是需要同步完成。并继续采用基于回调的异步方法。我想说的是,广播并不意味着是同步的。只是我的2分钱。
I take it that you are already aware of the standard synchronous versus asynchronous trade-offs, and situations where they are advantageous and not so.
IMO, your approach is okay only if the broadcast is also sent by your own application. If you are interested in a system broadcast, then the 5 second delay could vary between acceptable and catastrophic. Imagine registering for a "photo taken" broadcast, and then 5 seconds later when the user is taking another photo, your synchronous call returns and you display something thus annoying the user no end.
Also, how do you propose to deal with cases where the Broadcast is not a one-time, but rather continuous in nature?
I had tried to design an API using
AsyncTask
under the covers; and to expose it in a synchronous way. But it turned out that the usage of this API would be much more confusing for client code. I concluded that certain things are just not meant to be done synchronously; and went ahead with a callback-based async approach. Point I'm trying to make is, Broadcasts are just not meant to be synchronous.Just my 2 cents.
我不明白你到底想达到什么目的。
主播是谁?接收者是谁?对库和客户端代码之间的通信进行更好的描述会很有帮助。
无论如何,广播都是异步的(sendBroadcast)。接收器将在 UI 线程上被调用,这就是它同步起作用的地方。但它不保证什么时候会被调用。 Android系统会尽快做到这一点。
通过睡眠接缝进行同步是一个非常错误的设计决策,并且这不是广播应该使用的用途。
如果您需要同步回调,我会推荐侦听器模式,就像 android 所做的那样:例如 onClick 接口。
I don't understand what you're trying to achieve exactly.
Who's the broadcaster? Who's the receiver? A better description of the communication between the library and the client code would be helpful.
Broadcasts are asynchronous anyway (sendBroadcast). The receiver will be called on the UI Thread, that's where it acts synchronously. But it does not guarantee when it will be called. The android system will do that as soon as possible.
Synchronizing by a sleep seams like a really wrong design decision and it's not what broadcasts should be used for.
If you need a synchronous callback I would recommend the listener pattern, like android does: e.g. onClick interface.
基础知识! - 同步
basics ! - synchronization