Я читал некоторые подобные вопросы здесь, но из-за отсутствия представленного кода я не уверен, что мой вопрос описывает те же сценарии.
Я надеюсь, что следующие фрагменты и вопросы помогут другим прояснить, что и когда что-то просочилось в этой реализации MVP: https://github.com/frogermcs/GithubClient/tree/1bf53a2a36c8a85435e877847b987395e482ab4a
BaseActivity.java:
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupActivityComponent();
}
protected abstract void setupActivityComponent();
}
SplashActivityModule.java:
@Module
public class SplashActivityModule {
private SplashActivity splashActivity;
public SplashActivityModule(SplashActivity splashActivity) {
this.splashActivity = splashActivity;
}
@Provides
@ActivityScope
SplashActivity provideSplashActivity() {
return splashActivity;
}
@Provides
@ActivityScope
SplashActivityPresenter
provideSplashActivityPresenter(Validator validator, UserManager
userManager, HeavyLibraryWrapper heavyLibraryWrapper) {
return new SplashActivityPresenter(splashActivity, validator,
userManager, heavyLibraryWrapper);
}
}
SplashActivityPresenter внедряется внутри SplashActivity.java:
public class SplashActivity extends BaseActivity {
...
@Inject
SplashActivityPresenter presenter;
@Override
protected void setupActivityComponent() {
GithubClientApplication.get(this)
.getAppComponent()
.plus(new SplashActivityModule(this))
.inject(this);
}
SplashActivityPresenter.java:
public class SplashActivityPresenter {
public String username;
private SplashActivity splashActivity;
private Validator validator;
private UserManager userManager;
private HeavyLibraryWrapper heavyLibraryWrapper;
public SplashActivityPresenter(SplashActivity splashActivity,
Validator validator, UserManager userManager,
HeavyLibraryWrapper heavyLibraryWrapper) {
this.splashActivity = splashActivity;
this.validator = validator;
this.userManager = userManager;
this.heavyLibraryWrapper = heavyLibraryWrapper;
//This calls should be delivered to ExternalLibrary right after it will be initialized
this.heavyLibraryWrapper.callMethod();
this.heavyLibraryWrapper.callMethod();
this.heavyLibraryWrapper.callMethod();
this.heavyLibraryWrapper.callMethod();
}
public void onShowRepositoriesClick() {
if (validator.validUsername(username)) {
splashActivity.showLoading(true);
userManager.getUser(username).subscribe(new
SimpleObserver<User>() {
@Override
public void onNext(User user) {
splashActivity.showLoading(false);
splashActivity.showRepositoriesListForUser(user);
}
@Override
public void onError(Throwable e) {
splashActivity.showLoading(false);
splashActivity.showValidationError();
}
});
} else {
splashActivity.showValidationError();
}
}
}
- Если пользовательповорачивает экран во время извлечения имени пользователя, и мы просочились в экземпляр активности, на который ссылаются в обратных вызовах наблюдателя, поскольку действие уничтожено.
- Если пользователь поворачивает экран без выполняемой выборки, экземпляр действияне утечка.
- Чтобы исправить эту утечку (1), нам нужно сохранить подписку и отписаться от нее в Presenter.onDestroy () (вызывается из SplashActivity onDestroy ()).
- Кто-тосказал мне, что делать (3) недостаточно, и что внутри
onDestroy()
мы также должны установить экземпляр активности на null
.Я не согласен, потому что отмена подписки отменяет запрос, предотвращая обратные вызовы (например, onNext(User)
), которые ссылаются на активность, от вызова. - Он также сказал мне, что в то время как (3) и (4) предотвращают утечку активности, PRESENTER просочился во время ротации ТАКЖЕ, так как активность ссылается на него.Я не согласен, потому что новый презентатор создается для каждого поворота и инициализируется для внедренного презентатора, когда BaseActivity onCreate вызывает setupActivityComponent.Старый докладчик автоматически собирает мусор как участник SplashActivity.
Может ли кто-нибудь ответить на вопросы, изложенные выше, чтобы я мог подтвердить свое понимание или узнать, где я могу ошибаться?Спасибо