6thsolution / EasyMVP

A full-featured framework that allows building android applications following the principles of Clean Architecture.
http://6thsolution.github.io/EasyMVP
Apache License 2.0
1.3k stars 129 forks source link

[Discussion] Improving @PresenterId annotation #39

Closed RiccardoM closed 4 years ago

RiccardoM commented 7 years ago

From the last comment on #28:

@RiccardoM Thanks, EasyMVP calls getLoaderManager().initLoader(ID, ... , ... ); method, by default the ID is a simple counter object so when you create multiple instances of a class it will assign same id to them. There will be better solutions maybe, I think it can be simplified with putting ids in Bundle, but i encountered some bugs in custom Views.

What about using UUIDs as the presenteres' id?

Instead of passing the presenter id to its constructor and then associating it to the @PresenterId annotated object, a solution I came up with would be to have the same annotation (i.e. @Presenter) with a new boolean parameter (let's say keepInstance) that will act as follows:

I think that the resulting code inside the generator class would be something along the lines of this:

if (keepInstance) {
     presenterId = LOADER_ID.incrementAndGet() + "";
} else {
    presenterId = "view." + UUID.randomUUID().toString().replace("-", "");
}

This method shouldn't have problem with custom views or stuff like that, as the UUID is indipendent from the object that creates it.

What are your thoughts on this solution @SaeedMasoumi?

SaeedMasoumi commented 7 years ago

@RiccardoM Sounds good, but

EasyMVP calls loaderManager.initLoader(id,..) in each Activity, Fragment , View or Conductor Controller. By default for each view, the id is a hard coded generated integer (LOADER_ID.incrementAndGet()), For example loaderManager.initLoader(500,..), so loader manager can distinguish assigned loader to this view from others. In some situation that we need multiple instances of a same view class in an Activity or Fragment, we need to assign unique id to each instance. for example an activity has two MyCustomView as its children, So we should assign for example id = 100 to first view and id = 200 to second one. But important thing is when the activity is recreated we need to assign id = 100 to first view again and id = 200 to second one too, So loader can preserve Presenter.

So who can we find proper ids in configuration changes when we use multiple instances of a class?

Easiest solution is using @PresenterId, So we can change our initLoader method to loaderManager.initLoader(view.presenterId,..)

So as you see UUID will not work. Maybe this solution will work:

if(alreadyHasIdInBundle()) {
    loaderManager.initLoader(IdFromBundle(),..)
} else {
    id = generateAUniqueId()
    putIdIntoBundle(id)
    loaderManager.initLoader(id,..)
}