Having a singleton dataManager object which registers the OTTO listener in its constructor to listen to data ready event. In the application the dataManager is referred anywhere as
DataManager.instance.functionOfIt()
If not call GlobalOttoBus.instance.unregister(this) for this dataManger, then it’s listener function (fun getMessage(event: DataEvent)) may get call multiple times after reopen the app.
class DataManager {
private var mApplication: Application? = null
companion object {
val TAG = DataManager::class.java.name
private var dataMgr: DataManager? = null
val instance: DataManager?
@Synchronized get() {
return dataMgr
}
}
constructor(application: Application) {
mApplication = application
dataMgr = this
Log.e(TAG, "+++ DataManager:ctor(), GlobalOttoBus.instance.register()");
// have no way to to unregister in this DataManager ??? ???
GlobalOttoBus.instance.register(this)
}
@Subscribe
fun getMessage(event: DataEvent) {
Log.e(Tag, "+++ dataMgr::getMessage(), ${this}, ${event}")
onDataReady(event)
}
… …
}
Where the data is ready it posts the data to otto bus:
override fun onResponse(call: Call?, response: Response?) {
if (response!!.isSuccessful()) {
// parse the data ……
// then post data ready event
var dataEvt: DataEvent = DataEvent()
dataEvt.setPostData(posts)
Log.d(“GsonParse”, "+++ onResponse(), call GlobalOttoBus.instance.post(dataEvt): ${dataEvt} ")
GlobalOttoBus.instance.post(dataEvt)
}
It is observed when minimize the app (os destroys the application) and then reopen the app this DataManager’s constructor is called (a new instance in this new session) so it does the OTTO register listener again in it’s constructor.
The problem is where to unregister from the OTTO, or more of how to manage this singleton DataManager’s life cycle? After minimize the app and then reopen the app, seems the previous one is still alive/listen but not in the new app’s scope.
This is the trace
first time start app, the constructor:
08-19 11:32:33.558 5296-5296/xxxapplication E/DataManager: +++ DataManager:ctor(), GlobalOttoBus.instance.register(), this: DataManager@94fd499
after minimize the app and the reopen the app, the constructor is called again a new instance
08-19 11:34:14.141 5296-5296/xxxapplication E/DataManager: +++ DataManager:ctor(), GlobalOttoBus.instance.register(), DataManager@661f37d
one post:
08-19 11:34:15.242 5296-5380/xxxapplication W/GsonParse: +++ onResponse(), call GlobalOttoBus.instance.post(dataEvt): DataEvent@f5a0df6
two listeners called on different dataManager instances:
08-19 11:34:15.242 5296-5380/xxxapplication E/DataManager: +++ dataMgr::getMessage(), DataManager@94fd499, DataEvent@f5a0df6
08-19 11:34:15.395 5296-5380/xxxapplication E/DataManager: +++ dataMgr::getMessage(), DataManager@661f37d, DataEvent@f5a0df6
Find a workaround, implement the LifecycleRegistryOwner in mainActivity, so on the lifeCycle Lifecycle.Event.ON_DESTROY it means the activity is killed, so unregister the DataManger’s otto listener.
class MainActivity : AppCompatActivity(), LifecycleRegistryOwner {
private val mRegistry: LifecycleRegistry = LifecycleRegistry(this);
private var theLifeCycleObserve: TheLifeCycleObserve? = null
override fun getLifecycle() : LifecycleRegistry {
return mRegistry
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar = findViewById<Toolbar>(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
……
theLifeCycleObserve = TheLifeCycleObserve(lifecycle, object : TheLifeCycleObserve.OnLifeCycleChange {
override fun onStar() {
}
override fun onDestroy() {
DataManager.instance!!.unregisterOttoBus()
lifecycle.removeObserver(theLifeCycleObserve)
}
})
lifecycle.addObserver(theLifeCycleObserve)
}
………
}
class TheLifeCycleObserve(private var lifecycle: LifecycleRegistry?, private var lifeCycleChangeListener: OnLifeCycleChange?) : LifecycleObserver {
interface OnLifeCycleChange {
fun onStar()
fun onDestroy()
}
init {}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart() {
lifeCycleChangeListener!!.onStar()
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
lifeCycleChangeListener!!.onDestroy()
}
}