I've been trying to figure out how to stop all threads when my application is paused (when the 'Home' button is pressed) and I just can't figure it out.
Here's what I have: one main activity containing a tab host, every tab host has a list, when one item in the lists is clicked a new activity with details is started. Each list is within its own activity which starts an updater thread that makes sure the list content is always up to date.
Here's what I've tried: I've tried using the onPause(), onResume(), onStop() and onDestroy() events. The problem is that if I use either the main activity of the activity that holds a list to monitor for those events, they get called every single time an item from the list is clicked, as well as when the 'Home' button is actually pressed, so there's no way to distinguish between the situations.
Am I missing something? How is this usually done?
This is a pretty good indication that your design is flawed. You shouldn't ever have threads laying around that you can't account for or that don't finish themselves.
Each list is within its own activity
which starts an updater thread that
makes sure the list content is always
up to date
This kind of thing should be done in a service.
they get called every single time an
item from the list is clicked
This is how those events work. As soon as your activity is no longer visible (ie your new activity comes in front), it goes to onPause() and possibly onStop(). You have to account for this. You can't fight it, or work around it.
Related
When a user enters an activity on my app I want to perform some logic during onStart and possibly launch a second activity before letting the user see the first activity (think of this as a pin protected activity)
I have a small issue where the contents of the first activity are shown for a second before the second activity is started. This happens when the user uses the home button to get out and in to the app. Is there a way to prevent the first activity to be visible at all before performing the logic validation?
This is more of a "design" solution to your problem and not clear if it'll work for you. I had something similar in the app I'm working on. What I did instead, was to create an interstitial Activity that resembled the same starting state (i.e. not yet completely loaded) of the Activity (Pin-protected Activity in your case) that is about to be started. Once I'd made my appropriate decision about whether or not I could go on, I just navigated to that initial Activity. In your case, I could see you making the decision on this interstitial Activity, and then navigating to the Pin-protected Activity or to the other one if conditions were not met properly.
The only downside to this approach is that the app does a quick flash with the additional Activity, but I think the increased separation of logic is worth it.
I have an App with 2 activities A -> B. From B the user can update data being displayed by A, so I want A to show fresh data when the user navigates back (actually not so simple, some network involved so data can be updated at any time).
The activities are listening to ddbb changes so the views can be updated when data changes. Problem is data can change while activities are in background, so I am not sure when and how i should listen for changes. I can think of two approaches:
Listen for changes during the whole Activity lifecycle (onCreate - onDestroy) and just update the views when the data changes. This will update views from background activities.
Listen for changes only when the Activity is being active or displayed (between onStart/onStop or onResume/onPause) and force a view update every time the activity comes to the foreground (since changes might have happened while activity wasn't listening).
Mixed approaches; keep the listeners the whole lifecycle but only update views when activity comes to foreground.
Im not sure which is the correct way to handle data observing while in background.
Option 2 sounds more reasonable, but having to update the views when the activity comes to foreground may lead to UI lag right when the user starts interacting with the activity.
Option 1 will cause a lot of updates every time data is updated.
Thoughts on this?
You can choose any of the three options that suits your particular use case. Though I will say that the conventional use is with start/stop. onStart says that the activity is visible to the user in some way (either fully or partially) and onStop says that the activity is definitely not visible. So if you don't care to update the UI while the activity is not showing at all, use these lifecycle states.
You just may need to be prepared to capture data that you may have missed while the activity was stopped before it gets started again (for example, if the user pressed the home button, then came back to the activity via the task switcher. So performing your query again and rebuilding the contents of views from scratch may be necessary.
I'm having a hard time managing a back button in my app. If I'm not mistaken, the back button default function should return the user to their previous activity. But when I'm changing from one activity to another I call finish() in the listener. Because of the killed previous activity, pressing back button causes the app to exit.
Is there any way to preserve the previous activity and kill it only after the current activity has changed?
BTW, I know how to override the back button. But if I have a lot of activities, is it efficient to write an override for every activity that doesn't have previous acvitity already killed? I'm developing an RPG and I'm pretty sure there will be a lot of activities.
You're setting yourself up for a really bad time. You want to use as few activities as possible. In a game you really don't want to manage all of that data going back and forward between * amount of activities.
You need models to manage the game data, and your view activity can receive this data from a view controller. You don't want to kill you main view activity and you don't want to keep a bunch of activities in memory. Read a few chapters from this book. Good luck!
http://danielrparente.files.wordpress.com/2013/01/rpg_design_patterns_9_26_05.pdf
I am calling a method that populates a spinner from files in onCreate Method? As per the life cycle of andriod goes after it stops or if i use another apps it shouldnt populate spinner. however it is populating. Can you tell me why?
Once it is populated in onCreate(), it will stay populated unless you quit the activity. If you use some other app or just press the home button the activity may not be destroyed. It might simply be in the paused state. Once you come back to your activity it will simply resume itself to the last state it was in i.e. the spinner will remain populated. Android might decide to kill activities in the paused state as well if memory is low.
If you want to quit the app, Press the back button while you are in the activity. Then the activity will probably be destroyed and when you open it again, onCreate() will be called and the spinner will be repopulated.
I have an Activity that plays some audio from within a ListActivity. The user can also click on the list item and go to a more detailed view of that data. I want the audio to keep playing during that transition from one activity to another and keep playing once the detail activity is active BUT I also need to pause the audio if my activity is being paused or stopped for any other reason.
My issue is that I currently pause the audio in onPause() in the ListActivity because I want the audio to be paused when the user navigates away from my activity. E.g. when they press Home or Back. However, I don't want the audio to pause when my detailed view activity gets started. onPause() is called in both instances, so how can I distinguish between the two cases?
Shouldn't you be doing that in a service instead? Wouldn't it be easier? Then you can stop the service when one or another activity is pausing or exiting (depending on which one you want). You could also check if it's started, and stop accordingly whenever you want.
Or sorry if I didn't understand your question. I see you have a lot of points here on SO, so perhaps I'm just confused.
--- edited since your third comment:
A Intent to B: send Intent with name of music.
B onCreate: get name of music from Intent. Set flag x to true.
B onResume: start playing music if from A or resumes from last known position if resuming from B.
B back button: override and set x to false. Actually, you'd cover all points where your activity finishes.
B onPause: stop the music if(x), store last known position of music in memory and stop service.
Here I assume that you want music to keep playing even when returning to A (that's what you said, that's the problem), not just up to B. Setting x is important early on, IMO, because if any other activity (phone call, anything) appears, activity will stop playing the music immediately (user expects that) on onPause. According to Android guidelines, you know that you're getting back to A only if user presses back button or if you finish() your activity. You can fine tuning checking the position of activities in your task (don't remember how to do that right now).
Personally, I also wouldn't want to resume playback on A (say, B->call->home->A, applying step 3 to A, too), because a disruption in the logical flow of things happens there.
CAVEAT: I would make sure that there is no other way. I would try to see if you can 1) know in advance which activity is about to be displayed. 2) get any music service to hook up to your task (is that even possible?).
Anyway, just use my solution if you can't find a clever way to do that. That would be my suggestion. Good luck.