The problem: When I trying to rotate phone immediatelly after PullToRefresh, my Observable will not finish it's work because of dispose() method I calling in onPause. I understand why it's happening but I don't have any idea how to dispose without result loss. If I dont call dispose, everything works great but I want to dispose my Disposable correctly to have no problems with memory leaks and etc.
My base presenter:
abstract class BasePresenter<T> {
private var view: WeakReference<T>? = null
/**
* View reference
* */
fun getView(): T? = if (view != null) view!!.get() else null
/**
* We should call it in onResume() method in fragment
* */
fun bindView(view: T?) {
if (view != null) {
this.view = WeakReference(view)
updateView()
}
}
/**
* We should call it in onPause() method in fragment
* */
fun unbindView() {
view = null
dispose()
}
protected abstract fun updateView()
protected abstract fun dispose()
}
My base use case:
abstract class UseCase<TResult, in TParam> {
/**
* Creates a new instance of [Observable] for specified params
* @param params Params to create [Observable]
*/
abstract fun createObservable(params: TParam?): Observable<TResult>
/**
* [Observable] which executes UseCase logic for specified params
* @param params Params to create [Observable]
*/
fun observable(params: TParam?): Observable<TResult> =
createObservable(params).doOnError { }
/**
* [Observable] with null params
*/
fun observable() = observable(null)
}
In View:
...
override fun onResume() {
super.onResume()
presenter.bindView(this@MainFragment)
}
override fun onPause() {
super.onPause()
presenter.unbindView()
}
...
This is Observable code in presenter (handling some network response):
fun update() {
setRefreshing(true)
getDataDisposable?.dispose()
getDataDisposable = getDataUseCase
.observable(param)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.switchIfEmpty {
setRefreshing(false)
}
.subscribe { data ->
[some manipulations with data]
setRefreshing(false)
}
}
If I don't call this, everything (of course) works as expected:
override fun dispose() {
getDataDisposable?.dispose()
}
答案 0 :(得分:1)
最后找到了解决方案。现在,仅在按下后退按钮时才处理Disposable,而不要在未绑定的视图中进行处理。因此,我向基本演示者添加了方法:
...
/**
* Method that should be called on back button click in fragment
* It's planned that all [Disposable] objects will be disposed in implementation of this method
* */
abstract fun onBackButtonClicked()
...
演示者:
...
override fun onBackButtonClicked() {
getChartDataDisposable?.dispose()
}
...
查看(片段):
...
override fun onBackButtonClicked() {
presenter.onBackButtonClicked()
navigator.back()
}
...
还有一些拦截逻辑的单击硬件后退按钮:
接口:
interface OnBackButtonClickListener {
fun onBackButtonClicked()
}
基本片段:
abstract class BaseFragment : Fragment(), OnBackButtonClickListener {
...
override fun onResume() {
super.onResume()
(ctx as MainActivity).currentBackPressListener = this@BaseFragment
}
override fun onPause() {
super.onPause()
(ctx as MainActivity).currentBackPressListener = null
}
...
}
最后,在活动中重写onBackPressed()方法:
class MainActivity : AppCompatActivity() {
...
var currentBackPressListener: OnBackButtonClickListener? = null
...
override fun onBackPressed() {
currentBackPressListener?.onBackButtonClicked()
}
...
}