Activity
包含Fragment
,而Fragment
又包含一个Service
子请求Service
。该应用尝试实施dobjanschi休息架构。
当PendingIntent
完成工作时,它必须传播操作结果。我尝试使用{{1}},但它似乎只被活动捕获,而我需要子片段才能得到通知。你能提出什么建议吗?活页夹? greenRobot Eventbus? RxJava(我在项目中已有)?
感谢。
答案 0 :(得分:6)
一种简单的方法是使用Singleton来包装同步的'PostSubject'
* Singleton
*
* to send an event use EventBusRx.getInstance().topic1.onNext("completed");
*/
public class EventBusRx {
private static EventBusRx ourInstance = new EventBusRx();
public static EventBusRx getInstance() {
return ourInstance;
}
private EventBusRx() {}
/**
* Use of multiple topics can be usefull
* SerializedSubject avoid concurrency issues
*/
public final Subject<String, String> topic1 = new SerializedSubject<>(PublishSubject.create());
public final Subject<Integer, Integer> topic2 = new SerializedSubject<>(PublishSubject.create());
}
您可以从服务
发送事件EventBusRx.getInstance().topic1.onNext("completed");
并以片段或随时响应事件
public class MyFragment extends Fragment {
// [...]
Subscription subscription_topic1;
@Override
public void onResume() {
super.onResume();
subscription_topic1 = EventBusRx.getInstance().topic2
.subscribeOn(AndroidSchedulers.mainThread()) // or on other sheduler
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
// update ui
}
});
}
@Override
public void onPause() {
// important to avoid memory leaks
subscription_topic1.unsubscribe();
super.onPause();
}
}
不要忘记取消订阅订阅
这个想法类似于Roger'one使用单例,但强制执行ThreadSafety包装PublishSubject。
不需要Observable.switchOnNext(subject)
greenRobot Eventbus和Otto很不错并具有相同的功能,但缺点是它们使连接更加烟雾(特别是EventBus)。如果你已经使用rx我觉得最好还是坚持下去
这是一篇关于该主题的文章 Implementing an Event Bus With RxJava
这样做的经典方法是使用LocalBroadcastManager,但在我的意见中,他们是痛苦的
答案 1 :(得分:0)
试试这种方式希望它可以帮助你。
例如:
<强> YourService 强>
public class MyService extends Service{
public static MyServiceListener getMyServiceListener() {
return MyService.myServiceListener;
}
public static void setMyServiceListener(MyServiceListener myServiceListener) {
MyService.myServiceListener = myServiceListener;
}
private static MyServiceListener myServiceListener;
public interface MyServiceListener{
void onResult(String response);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
executeYourTask();
}
private void executeYourTask(){
String result = "SomeResultMaybeFromServer";
if(getMyServiceListener()!=null){
getMyServiceListener().onResult(result);
}
}
}
<强> YourFragment 强>
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = null; // some view
// Start service
MyService.setMyServiceListener(new MyService.MyServiceListener() {
@Override
public void onResult(String response) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// To handle memory/window leaks
}
});
}
});
return v;
}
}
答案 2 :(得分:0)
我建议使用事件总线进行此类操作。它允许您向系统中的组件发送消息,而无需创建特殊的处理程序。
Otto是一个流行的开源库,还有其他的。 http://square.github.io/otto/
答案 3 :(得分:0)
我目前正在开发一个仅基于RxJava的总线。由于您的项目已经有RxJava,因此可以使用它。您应该使用BehaviorSubject和Observable.switchOnNext()。
例如:
private BehaviorSubject<Observable<Whatever>> subject = BehaviorSubject.create();
public void post(){
subject.onNext(...);
}
public Observable<Whatever> subscribe(){
return Observable.switchOnNext(subject);
}
您应该将此作为Singleton的一部分,因此使用相同的BehaviorSubject。您所要做的就是从一个片段发布post(),在另一个片段或任何其他感兴趣的片段或活动中订阅()。你可以拥有任意数量的订阅,如果你正确实现它,那么最后发出的Observable将会在方向更改后继续存在。
有关BehaviorSubject的更多信息,请访问:https://github.com/ReactiveX/RxJava/wiki/Subject
答案 4 :(得分:0)
我目前正在使用此发布/订阅模式与rxjava和枚举类。
public enum Events {
public static PublishSubject <Object> myEvent = PublishSubject.create ();
}
//你要发布的东西
Events.myEvent.onNext(myObject);
//您希望收到活动的地方
Events.myEvent.subscribe (...);
答案 5 :(得分:0)
我会使用基于rx的事件总线。 将此作为sigletone并订阅特定的类类型。
public class RxBus {
private static final RxBus sBus = new RxBus();
private final Subject<Object, Object> mBus = new SerializedSubject<>(PublishSubject.create());
private RxBus() {
}
public static RxBus getInstance() {
return sBus;
}
public void send(Object o) {
mBus.onNext(o);
}
public Observable<Object> observe() {
return mBus;
}
@SuppressWarnings("unchecked")
public <T> Observable<T> observe(Class<T> c) {
return mBus.filter(o -> c.isAssignableFrom(o.getClass())).map(o -> (T) o);
}
}
用法:
class Message { public String result};
发送消息:
Message m = new Message();
m.result = "Hello world";
RxBus.getInstance().send(m);
订阅特定的班级类型:
RxBus.getInstance().observe(Message.class).subscribe(msg -> Log.e(TAG, "Message was caught : " + msg));