- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Mosby 创建一个小应用程序。
该应用程序有一个我想要绑定(bind)的服务。我想正确的位置是在演示者中。但我实在不知道该怎么做。
我想要存档的是,当服务绑定(bind)时,我想调用它的方法并将该值推送到 View ,以便现在的状态是正确的。
当服务在事件总线上发送更新时,我也想将其推送到 View 。
我在后面的部分找到了一些示例,但没有介绍如何在演示者中绑定(bind)/取消绑定(bind)服务。
我的尝试是在 Activity 中创建类似的东西:
@NonNull
@Override
public MyPresenter createPresenter() {
return new MyPresenter(new MyService.ServiceHandler() {
@Override
public void start(ServiceConnection connection) {
Intent intent = new Intent(MyActivity.this, MyService.class);
startService(intent);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
@Override
public void stop(ServiceConnection connection) {
unbindService(connection);
}
});
然后在演示者中执行如下操作:
private ServiceConnection connection;
private boolean bound;
private MyService service;
public MyPresenter(MyService.ServiceHandler serviceHandler) {
super(new MyViewState.NotInitialiezedYet());
this.serviceHandler = serviceHandler;
connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
MyService.LocalBinder binder = (MyService.LocalBinder) service;
service = binder.getService();
bool isInitialized = service.isInitialized();
// how do i push isInitialized to view?
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
}
@Override
public void attachView(@NonNull SplashView view) {
super.attachView(view);
serviceHandler.start(connection);
bound = true;
}
@Override
public void detachView(boolean retainInstance) {
super.detachView(retainInstance);
if(bound) {
serviceHandler.stop(connection);
bound = false;
}
}
@Override
protected void bindIntents() {
//Not sure what this would look like?
}
public void onEventInitialized(InitializedEvent event) {
//how do I push this to the view?
}
我走的路正确吗?这样做的正确方法是什么?当我在 onEventInitialized 中的事件总线上获取事件时,如何将值从服务发送到 onServiceConnected 中的 View ?
最佳答案
在我们深入研究可能的实现之前,需要注意一些事项:
Activity
中创建 ServiceHandler
,则会出现内存泄漏,因为 ServiceHandler
是在 Activity 中实例化的匿名类,因此引用了外部 Activity 实例。为了避免这种情况,您可以使用 Application
类作为上下文来调用 bindService()
和 unbindService()
。MyServiceInteractor
。 detachView()
中完成了该操作。虽然这有效,但 Presenter 现在对业务逻辑内部结构及其工作原理有了一些明确的了解。一个更类似于 Rx 的解决方案是将服务连接的生命周期与 Rx Observable 的“生命周期”联系起来。这意味着,一旦取消订阅/处置可观察对象,就应该关闭服务连接。这也与 1.“演示者在屏幕方向变化中幸存”(并在屏幕方向变化期间保持可观察的订阅处于 Activity 状态)完美匹配。Observable.create()
可以轻松地将任何回调/监听器“包装”到 Rx Observable 中。话虽如此,让我们看看可能的解决方案是什么样的(伪类似代码,可能无法编译):
public class MyServiceInteractor {
private Context context;
public MyServiceInteractor(Context context) {
this.context = context.getApplicationContext();
}
public Observable<InitializedEvent> getObservable() {
return Observable.create(emitter -> {
if (!emitter.isDisposed()) {
MyService.ServiceHandler handler = new MyService.ServiceHandler() {
@Override public void start(ServiceConnection connection) {
Intent intent = new Intent(context, MyService.class);
context.startService(intent);
context.bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
@Override public void stop(ServiceConnection connection) {
context.unbindService(connection);
}
};
emitter.onNext(handler);
emitter.onComplete();
}
}).flatMap(handler ->
Observable.create( emitter -> {
ServiceConnection connection = new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) {
MyService.LocalBinder binder = (MyService.LocalBinder) service;
MyService service = binder.getService();
boolean isInitialized = service.isInitialized();
if (!emitter.isDisposed())
emitter.onNext(new InitializedEvent(isInitialized));
}
@Override public void onServiceDisconnected(ComponentName name) {
// you may want to emit an event too
}
};
})
.doOnDispose({handler.stop()})
);
}
}
因此,基本上,MyServiceInteractor.getObservable()
创建了通往 Rx Observable 世界的桥梁,并在可观察 get 取消订阅时停止服务连接。请注意,此代码 fragment 可能无法编译。这只是为了说明可能的解决方案/工作流程的样子。
那么您的 Presenter
可能如下所示:
public class MyPresenter extends MviBasePresenter<MyView, InitializedEvent> {
private MyServiceInteractor interactor;
public MyPresenter(MyServiceInteractor interactor){
this.interactor = interactor;
}
@Override
void bindIntents(){
Observable<InitializedEvent> o = intent(MyView::startLoadingIntent) // i.e triggered once in Activity.onStart()
.flatMap( ignored -> interactor.getObservable() );
subscribeViewState(o, MyView::render);
}
}
所以这里的主要问题/问题并不是 MVI 或 MVP 或 MVVM 具体的,主要是我们如何将 android 服务回调“包装”到 RxJava 可观察中。一旦我们有了这个,剩下的就很容易了。
唯一与 MVI 相关的事情是连接点: View 实际上必须触发启动服务连接的 Intent 。这是通过 myView.startLoadingIntent()
bindIntents()
中完成的
希望对您有所帮助。
关于Android Mosby MVI 绑定(bind)到演示者中的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43042785/
我尝试添加 Mosby library到我的宠物项目,但我不明白如何将它包含到项目中? 我尝试通过添加为模块-> 添加为 Gradle 项目来添加 mosby,但它无法编译。 请给我链接一些教程,如何
我正在寻找一种将基类添加到 mosby 的方法MVP Activity 。让我解释一下我需要什么。 通常在使用 mosby 时我们会声明这样的 Activity : public class Logi
我将 Mosby MVI 库用于一个演示应用程序,该应用程序在我的交互器中使用 Retrofit2 对 Restful API 执行简单的 CRUD 操作。我构建的 ViewStates 与示例应用程
我的演示者如下所示: // I'm retaining the presenter in a singleton instances map and reuse them // because the
我正在使用 Mosby 创建一个小应用程序。 该应用程序有一个我想要绑定(bind)的服务。我想正确的位置是在演示者中。但我实在不知道该怎么做。 我想要存档的是,当服务绑定(bind)时,我想调用它的
我只是创建了一个简单/空白的 fragment ,它应该使用 Mosby 框架。每次我使用 getView() 方法时都会收到错误消息: java.lang.ClassCastException: d
我正在开发一款 Android 应用。我附加的代码正在创建一个回收 View 。我们做的第一件事是创建一个异步任务,它将在 SQLite 数据库上获取数据并将其加载到适配器->recylcerview
我正在使用 Mosby Android 应用程序中的模型- View -Presenter 库。在一个特定的 View 中,我正在使用 Bottom Navigation用 Design Suppor
我正在尝试使用 Mosby 实现一个 MVP Android View(不是 Activity 或 fragment ),但是当在 Android Adaptor 中使用该 View 并在 onBin
我正在尝试在 Android 中实现 MVI 架构,但不想使用 Mosby 库。我想先学习基础知识。 我正在构建一个示例应用程序,当我按下按钮时, TextView 中的文本会发生变化(最初文本是其他
尽管在下游处理了错误(?),但我还是抛出了 OnErrorNotImplementedException 并且应用程序崩溃了。 异常 E/AndroidRuntime: FATAL EXCEPTION
我正在尝试理解 MvP 设计模式的概念。我的意思是,我明白了,这很容易。主要问题是最佳实现。我试图制作自己的 BaseActivity、BasePresenter 和 BaseView,只是为了从我的
我正在尝试在 Dagger 2 中使用 Mosby 的 MvpBasePresenter 设置一个 Base Presenter 我有以下基本组件: public interface BaseView
我是一名优秀的程序员,十分优秀!