Open mheras opened 9 years ago
Hi!
@konmik Thanks for your response! I have another one:
destroyPresenter
method on NucleusLayout
. Is it somewhere else now?@konmik Something like ((ViewWithPresenter)myView).getPresenter().destroy();
?
Yes, this is how it should work now.
I use this method for fragments as well: https://github.com/konmik/nucleus/blob/master/nucleus-example-with-fragments/src/main/java/nucleus/example/main/MainActivity.java#L19
@konmik Great! Yet another question for you:
I need the deliver
and deliverLatest
functionalities (actually the restartable*
alternatives) that are explained in your MVP Introduction, but I cannot find them in the latest version of the library. Did you move them to another place?
I'm trying to achieve a paginated list (with a RecyclerView
), but every time the view is taken by the presenter, the latest response is getting appended to the list (because I'm using restartableLatestCache
). I think something similar to deliver
will help me with this use case.
As always, thank you for your time.
P.S.: Please let me know if you don't feel comfortable with this issue being treated as a Q/A thread :)
I think that paging should deserve a wiki page: https://github.com/konmik/nucleus/wiki/Paging-example
deliver
and deliverLatest
has been superseded by deliverLatestCache
, deliverFirst
and deliverReplay
.
Hey, just wanted to pop in and ask a question. I have used the deliver()
transformer before. Coming into v2.0.1, I had to settle for deliverReplay()
. I am observing that myObservable.compose(deliverReplay())
is emitting source observable's onError
events as onNext
events. Any insights into this if this is not a bug but a feature?
Sure, this is not a bug.
When we construct a connection we don't want to create it every time we request something - we want our connections to be reused. This is why all events come in the materialized state and this is why we use split
at the end of a chain.
I also have some doubts when subscribing in onTakeView
method. All the examples I've seen here use onCreate
, but what if you need some data from the view to make a request? (for example, an id from an activity's intent), and surviving screen rotation?
At the moment, I'm following this pattern https://gist.github.com/inorichi/158fa261f8ef7d3e7dde
Is this approach the way to go? Or did I miss something? I haven't tried with restartables in this case, is it an option?
Edit: I've edited the gist to show two options. One of them for what I've said before, and the other for reacting to user input.
PD: Thank you so much for Nucleus. Before this, I was using some kind of MVP where the presenter was doing almost everything and the code flow was getting very ugly.
Hi,
How about writing something like this? (pseudocode)
class MyActivity {
onCreate() {
if (savedState == null)
getPresenter().requestData(getIntent.getExtra());
}
class MyPresenter {
int id;
onCreate(state) {
this.id = state.id;
registerRestartable(1, () -> api.getData(id),
MyView::onData,
MyView::onError);
}
void request(int id) {
this.id = id;
start(1);
}
Bundle save() {
return new Bundle("id" = this.id);
}
This is what I was looking for. Thanks!
Hello. Quick question for you:
I'm trying to create a Google Now like user interface (several different CardViews
inside of a RecyclerView
). I'd like each CardView
to have its own presenter that is responsible for loading data (from the network, DB, etc.).
It seems like the only way to detect when a view is being recycled/rebound within an RecyclerView is to override the View.onStartTemporaryDetach()
and View.onFinishTemporaryDetach()
callbacks. I'm considering using those to drive the PresenterDelegate.onResume()
and PresenterDelegate.onPause()
events.
Do you foresee any issues with that or have any other recommendations?
@gautamjain Hi, forsee tons of problems with the approach because card's lifecycle will be too short and they will disappear while scrilling, so you will need to keep track of all presenters to destroy them manually on exit. You will also need to manually save/restore card's state because RecyclerView does not do that.
hi i am using ur library to handle , states for a list view , for instance when the data is not loaded a load screen , and when the data (via api call ) has been received then i change the layout of the activity to something say loadedLayout , but as i get the activity instance from view().subscribe(Activity ) , i am getting a null instance for the activity , is there any work around this issue (attached code)
restartableLatestCache(REQUEST_ITEMS,
new Func0<Observable
@kushaga Hi, you normally do not need to use view()
directly, there is example you can look up into: https://github.com/konmik/nucleus/blob/master/nucleus-example/src/main/java/nucleus/example/main/MainPresenter.java
Having null from view()
is absolutely normal - you get it when view gets detached (read the view()
method JavaDoc). If you don't need it just use the usual RxJava filter
operator.
Hi! Quick question- I have included the library - compile 'info.android15.nucleus:nucleus-support-v7:2.0.5' in my gradle dependencies. But I am not able to import NucleusAppCompatActivity. Am I missing something or has something changed?
@KScoder83 nothing changed. Try to re-import project or something.
I tried re-importing, but still it is not including the support libraries.
I would just copy NucleusAppCompatActivity
to your project and only include info.android15.nucleus:nucleus:2.0.5
as dependency.
@KScoder83 What if you just invalidate cache and restart? I have nucleus in several projects, it does fine. You can also download the support aar and expect it - classes are there. Try to invalidate caches, if it does not help then delete .gradle folder and idea files and re-create project.
Great thanks! it seems to do the trick
Hi, I'm using Nucleus in my project and now trying to add Dagger 2 support to it. What I can't figure out is - do I really need to use Nucleus with Dagger 2 or I just can have pretty much same functionality with dagger 2 scope mechanism?
Hi,I think there is no need to restart the undone job when process reboots. RxJava is just some kind of thing which can replaces the AsyncTask while it cannot replace Service. RxJava should ideally be used for short operations (a few seconds at the most.) in Android .If you need to keep threads running for long periods of time, it is highly recommended you use service.So it's not possible for the process to be killed for saving memory before the job dong by RxJava is done. We should keep long threads in the service process but not in background process.I doubt my opinion.Hope to see your reply .
Hi @duo2005duo,
How do you solve the progress bar problem without restarting background tasks?
I don't quite get why you oppose RxJava to services. RxJava is a language extension library. Service as an Android architecting solution for synchronization and background tasks with notifications. They work together without problems.
Hi @bejibx
You can use Nucleus with Dagger easily, here is an example (Dagger 1): https://github.com/konmik/nucleus/tree/master/nucleus-example-with-tests
Dagger can't restart background tasks.
How about Dagger 2? I mean, the main idea of Nucleus is to keep presenters separated from Activity lifecycle by moving them to static storage. I am trying to understand Dagger 2 right now (btw thank you for your "Snorkeling with Dagger 2" article) and it seems scopes mechanism is doing just this - "In Dagger 2 scopes mechanism cares about keeping single instance of class as long as its scope exists". So I wonder do I really need to use Nucleus in my project if I'm already using Dagger 2? Or I can get same thing with only Dagger 2 scopes mechanism? The problem is I'm not so familliar with Dagger 2 so I'm really not sure.
@bejibx the purpose of Nucleus is to reduce application complexity by restoring background tasks together with view state, and by automatical reattachment of background tasks if they're still running.
Dagger 2 can't do this. Everything you created with dagger 1 or dagger 2 will be wiped out during a process restart.
@konmic yes, you're right. But what if my presenters are stateless?
@bejibx You can't save background task arguments then, so you can't restart those tasks with Nucleus.
@konmik Take downloader for example,when the user press home button in a activity with a downloading progressbar ,you have to start a foreground to push noifications to indicate the current progress and the service will keep the process going on.The process will not be killed for saving memory when there is a foreground service in the process. In my opinion,the long pieriods of task should be place in the service and you do not need to restart tasks when process reboots. I'm talking about the reboot of the process but not the recreate of the activity. In the source of Nucleus,you regist a lot of restarable task and put the startId into the ”savedInstanceState“ which make the task restart if process reboot. I think there is no need to do so becasue long pieriods of task always come with foreground service.
@duo2005duo sure, if a task is going to live longer than activity it is a good idea to put it into a service. But if it doesn't it is better to have it restartable.
I think you may probably do not get what happens with background tasks when your app is in the background and Android decides to free some memory. There is a clear statement about this in the project readme and in the article. I tried to be as clear as possible, put it looks like some people just do not believe that Android works like that. You may play around with lifecycles and see it yourself. Restarting background tasks is the only reliable solution to Android lifecycles.
@konmik I had read the readme before. if a task is going to live shorter than activity,it is going to live shorter than process.Is there anything wrong?So startable can work for activity-recreate and process-reboot,but there is no need to make it work during process-reboot because we use service instead,if process-reboot may be going to happen during the task,service is a better choice to be the holder of task.
@duo2005duo Activity life is longer than life of its process!
@konmik Oh, I make a mistake,I think I get it. Thanks a lot!!!
another question: In your demo
@RequiresPresenter(MainPresenter.class)
public class MainActivity extends NucleusActivity<MainPresenter>
I think the following code blocks are better if we do not use Dagger,which separate P from V
@RequiresPresenter(MainPresenter.class)
public class MainActivity extends AbstractMainActivity //abstract
...
public abstract class AbstractMainActivity extends NucleusActivity<AbstractMainPresenter>
Do you think so? If you think so,how to separate P from M in Nucleus in this way?
@duo2005duo I think that you can use the AbstractMainPresenter
and return any implementation in getPresenterFactory()
method override. Without use @RequiresPresenter
@cavarzan Yes,but what's the benifit about using getPresenterFactory()
instead of @RequiresPresenter
?
@duo2005duo lazy initialization or need to create the presenter using dependency injection.
I would write something like this instead:
public abstract class AbstractActivity<P extends AbstractPresenter> extends NucleusActivity<P>
@konmik if so,
public abstract class AbstractPresenter<P extends AbstractActivity<******>> extends Presenter<P>
And then another Java propblem happens
public abstract class AbstractActivity<P extends AbstractPresenter<******>> extends NucleusActivity<P>
**\ looks like a circle.How to sovle it?
@duo2005duo You don't need the type in AbstractPresenter
@cavarzan @konmik Thanks
@konmik Hi,I comes again. Is it a correct way to keep the task going on when a activity has been finished by the system? The system can drop the activity from memory by either asking it to finish, or simply killing its process.it seems the task is still running when system ask activity to finish although the activity may not be displayed again.
@duo2005duo we have no way on android to cancel background tasks immediately on activity finish. If you're using nucleus, it just automatically unsubscribes from data sources and the rxjava contract is that it stops working immediately or some time after.
@konmik Yes,the task will finish as soon as possible if it unsubscribes from data sources. But it seems the task can only unsubscribe automatically when activity runs in onPause()
with the state of finish.But the system can only drop the activity after onStop()
by asking it to finish if the activity has been in background for a long time.
@konmik I have proved that the task is still running and nucleus never unsubscribe from data if the system ask a activity to finish ,which I think it's a waste of system resource and it will also cause OOM if too many obervers is unsubscribed .I think retained fragment should be used to hold the Presenter instead of a StaticHolder.
PS: The isFinishing()
still return false when the system ask a activity to finish.So I think using retained fragment to unsubscribe from data in fragment.onDestroy()
is preferred.
@duo2005duo This is a rare use case. But you're right, we need a fix for this. I'm thinking about calling presenter's onDestroy
during activity's onDestroy
.
Retained fragment does not look like a valid variant because its lifecycle is not what we need to continue background tasks, see my original MVP article.
@konmik Yes,we need to save/restore such fragment's state anyway.Using staticholder can reduce this pocedure but it seems we cannot tell the reason why the activity run into onDestroy
(Configuration change or finished by system).
@konmik, Do you have any working examples of pagination? What exactly is the request.get(page) here? Is it the getItemsList request?
restartableReplay(1,
() -> pager.pages().<PageBundle<List
@droid2009der Yes it is. The working example is in the wiki.
Hi!
I'm working on an app I want to use Nucleus for MVP+Rx.
I have some doubts, and I couldn't find any solution in the documentation/wiki. Could you please help me?:
1) How can I use two instances of the same view, and make each of them have their own instances of their presenters? Is it possible by telling the
PresenterStorage
with ID to use? Or by any other way?2) Why is the presenter being destroyed and pointed to null in the
onPause
method instead of doing so inonDestroy
? The documentation seems to be out of date. What if I want to stack several activities of the same type, and want them to keep their presenters while not destroyed by the system? Is that working because you passisFinishing()
to the delegate?3) I think we need more documentation about the
restartable*
methods inRxPresenter
. I know that it is documented in the code with Javadoc, but I think it would be great to add some explanation in the wiki. Something like thedeliver*
methods documentation (btw, some of them seem to be out of date since you released version 2.0.1).Thank you very much. Your library is great. Cheers, M.