Mosby & EventBus
Я пытаюсь разработать приложение, используя Mosby и EventBus. Первое событие, которое я хочу получить, - это после входа в систему пользователя, создание события с привязкой, чтобы каждый экран мог получить доступ к информации для входа в систему в любое время.
Основываясь на образце почты Mosby, у меня есть BasePresenter, как это:
public abstract class EventBusPresenter<V extends MvpView> extends MvpBasePresenter<V> {
private static final java.lang.String TAG = tag(EventBusPresenter.class);
@Inject
protected EventBus mEventBus;
LoginSuccessfulEvent userInfo;
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onLoginSuccessful(LoginSuccessfulEvent event) {
MCLog.i(TAG, "Received a login event!");
userInfo = event;
onLoginReceived(event);
}
protected abstract void onLoginReceived(LoginSuccessfulEvent e);
public LoginSuccessfulEvent getUserInfo(){
return userInfo;
}
@Override
public void attachView(V view) {
super.attachView(view);
mEventBus.register(this);
}
@Override
public void detachView(boolean retainInstance) {
super.detachView(retainInstance);
mEventBus.unregister(this);
}
}
Когда пользователь входит в систему, я использую этот код:
public void doLogin(String username, String password) {
if (isViewAttached()) {
getView().showLoading();
}
cancelSubscription();
mSubscriber = new Subscriber<AuthenticationResponse>() {
@Override
public void onCompleted() {
if (isViewAttached()) {
getView().loginSuccessful();
}
}
@Override
public void onError(Throwable e) {
if (isViewAttached()) {
getView().showLoginError();
}
}
@Override
public void onNext(AuthenticationResponse authenticationResponse) {
User user = authenticationResponse.getUser();
MCLog.w(TAG, String.format("Login was successful with user: %s", user) );
mEventBus.postSticky(new LoginSuccessfulEvent(user, authenticationResponse.getToken()));
String token = authenticationResponse.getToken();
MCLog.i(TAG, String.format("Token obtained = %s", token));
mSharedPreferences.edit().putString(PreferenceKeys.TOKEN_KEY, token).apply();
}
};
Моя идея состоит в том, что для каждого экрана, как только он загружен, он может получить UserInfo через подписку EventBus.
Вопрос в том, что это событие прибывает тоже, сын. В соответствии с собственным классом BaseFragment Мосби я делаю это:
public abstract class BaseFragment<V extends MvpView, P extends MvpPresenter<V>> extends MvpFragment<V, P> {
private Unbinder mUnbinder;
@LayoutRes
protected abstract int getLayoutRes();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(getLayoutRes(), container, false);
}
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
inject();
super.onViewCreated(view, savedInstanceState);
mUnbinder = ButterKnife.bind(this, view);
}
@Override public void onDestroyView() {
super.onDestroyView();
mUnbinder.unbind();
}
/**
* Inject dependencies
*/
protected void inject() {
}
}
Это означает, что внедрение происходит до создания представлений, поэтому всякий раз, когда я пытаюсь ответить на полученное событие LoginEvent, элементов пользовательского интерфейса, которые необходимо обновить, больше нет.
Как мне этого добиться? Это даже правильный способ сделать это?
1 ответ
Делать mUnbinder = ButterKnife.bind(this, view);
либо в onCreateView()
или если вы предпочитаете делать это в onViewCreated()
вызов mUnbinder = ButterKnife.bind(this, view);
перед звонком super.onViewCreated()
,
Btw. Использование EventBus для этого звучит больно. Почему бы просто не иметь класс, как UserMananger
где вы можете получить текущего аутентифицированного пользователя или ноль, если пользователь не аутентифицирован. Кроме того, поскольку вы используете RxJava, имеет смысл включить UserManager
в вашей цепочке / потоке RxJava на каждом экране.