Typically applications cannot be "restored to the last screen" without also performing initialization.
For example, my app holds a live connection to a server which is established on initialization. It also needs to check for preconditions (like internet connection available, etc).
So when a user presses Home on the app and then restores the app, I need to restablish the connection (may require user input) and reinitialize everything.
I would've thought terminating the app on Home was the way to go, but from what I read, it's "not".
Just how are apps supposed to reinitialize themselves when restored on the Android platform?
note: I cannot use NO_HISTORY flag as it breaks the Google Play API.
Initialize the connections in the onStart method, and finish them in the onStop method, whenever the app loads up (new load of reloading) the onStart method will be called.
See the graphic here for more details about an activities lifecycle
Related
when I am in the last activity and I press back, my app goes to the background but when I return my app restarts going back to the "login" screen, if I am in "Home" and I go back it goes to the background because my login activity finished, I understand this is part of how the Android system works. Having an app with an sdk that uses bluetooh with asynTask tasks, I would like to be able to force an activity not to close or cancel when it goes to the background, I am looking for alternative solutions such as making the app stay in "widget" mode or being able to launch some kind of "service" that forces my activity as such not to close or restart when it goes to the background, I'm quite new to all this, any suggestion on how to solve this problem will be welcome
Backing out of the last Activity on the stack treats the app as "closed", and there are expected behaviours associated with that:
The user's assumption in these complete dismissal cases is that they have permanently navigated away from the activity, and if they re-open the activity they expect the activity to start from a clean state. The underlying system behavior for these dismissal scenarios matches the user expectation - the activity instance will get destroyed and removed from memory, along with any state stored in it and any saved instance state record associated with the activity.
So while it is possible to restore the previous state (the example they give is a web browser opening at the same page it was on) the system and components like Navigation are built around this idea that state shouldn't be preserved. You'd have to put in effort to work around that.
Running a Service only keeps your app's process alive - it won't do anything for background Activities, which the system will destroy if it needs the memory. And besides, like it says above, if you back out of an Activity it's considered dismissed and its state is wiped, whether it's been kicked out of memory or not.
Honestly it sounds like you just want to avoid redisplaying the login screen if the user's already logged in? That shouldn't be anything to do with Activity state, you should be storing that data somewhere so you can check it when the app starts, so you can send them to the appropriate screen
There's a whole section about this exact scenario in the Navigation docs. They don't show their UserViewModel (which we're supposed to imagine handling logged-in state, and actually doing the user/password auth if necessary) but the idea is pretty simple - you have a component that exposes a value saying whether the user is logged in or not (which could be stored in e.g. SharedPreferences) and it can automatically navigate away from the login screen based on that.
Im using in my app the onDestroy method to clean up data.
Google's documentation says documentation
Note: do not count on this method being called as a place for saving
data! For example, if an activity is editing data in a content
provider, those edits should be committed in either onPause() or
onSaveInstanceState(Bundle), not here. This method is usually
implemented to free resources like threads that are associated with an
activity, so that a destroyed activity does not leave such things
around while the rest of its application is still running. There are
situations where the system will simply kill the activity's hosting
process without calling this method (or any others) in it, so it
should not be used to do things that are intended to remain around
after the process goes away.
Such a situation is swiping the app out of the recent tasks list.
So in this case, data and other user important information must be saved in onPause or orStop().
But according to this link, none of the lifecycles get called.
So where do we save our data?
But according to this link, none of the lifecycles get called.
That answer is somewhat misleading. Your foreground activity should no longer be in the foreground when the user brings up the overview screen (recent tasks list). onPause() and onStop() will be called on that activity as a result. You can test this by overriding onPause() and onStop() and logging their calls.
So where do we save our data?
That depends a lot on what you are building.
In some cases, save the data when the data changes and the user indicates that they want to hold onto this data.
In some cases, save the data periodically. For example, in a game, you might save the game state every so often, so the user can pick up the game from where they left off.
In some cases, using a lifecycle method (e.g., onStop()) as a data-save trigger can be OK, but other times not. Saying "we will save the stuff that the user has typed in when we get called with onStop()" might be fine. Saying "we will go ahead and charge the user's credit card when we get called with onStop()" might not be fine.
I want to allow users to lock the device in a sports activities tracking app, to avoid unintentionally leaving the app while exercising.
Therefore I provide a button which locks the input controls of my app and in addition provides the option to lock also the home and overview button, by calling Activity.startLockTask().
I know, that I can call ActivityManager.getLockTaskModeState() later on to find out, whether the user accepted the lock or not.
But what is the best time to do that, or in other words, is there a reliable event that is called, when the popup provided by the system is accepted or rejected by the user?
I checked already that onResume of my activity is not called.
I also found DeviceAdminReceiver.onLockTaskModeEntering/Exiting. But this is meant for administrated devices only and I don't think it can be used without a lot of additional hassle (if possible at all).
I also hoped that the view, which is temporarily hidden by the system popup, gets any of its onWindowFocusChanged, onWindowVisibilityChanges or any other "onWhateverChanged" methods called. But no breakpoint was hit in the methods I tried to overwrite.
I have to add the following feature in my android application.
There is a client, when the client logs into the application, clicks a button to make themselves available to the user by going online. When he clicks the button a rest call is made, and which change the DB status(status changed to online) and make him online.
Now my problem is I want to make the client unavailable(offline) if the app is getting forced close or removed by android from the background due to low memory or removed by the user from the recent app. If any of these situations occur I do a rest call to handle the situation.
In the normal scenario if he is online he can simply click the button again to make a rest call which will change his status to unavailable(offline) in DB.
NOTE: I don't want to use onPause() or onStop() method because I want the client to be online even if he navigates out of the application and comes back.
In principle you can't because there's always a case when user can get disconnected without feedback (e.g. losing signal, battery).
IMO you should look for ways to detect the timeout from the server side, similar to socket.io disconnect() outlined in this SO answer.
I’m developing application for most major Mobile OS like iOS, Windows Phone and Android. I have a request from my client that simply possible to implement in iOS and WP but sounds really tricky in Android.
In iOS and WP, an application lifecycle is controlled through events which an object like UIApplication and Application receives.
In iOS, for ex., applicationDidEnterBackground:, applicationWillEnterForeground:, applicationWillTerminate: and the like, clearly define application states such as Inactive, Active and Background and make the app state management logic really straight forward.
In WP, Application receives well understanding events such as Launching, Deactivated, Activated, and Closing which make it really simple to decide what should be done in each app state logically to save as restore application wide object model.
But in Android, application state management sounds really difficult with Activities’ state changes such as onCreate, onRestart… onDestroy method overriding. My problem arises where I want to control the whole application state when the user session goes expired and I want to redirect user to the sign in activity and shuts down other open activity.
Regarding the fact that calling finish() in an activity’s onCreate(), onRestart() or onResume() is ignored by Android (according to the documentation) .
Even if I override android.app.Application and put the logic there, it sounds like controlling open activities is not possible.
I almost tried all possible combinations of activity launch mode (such as SingleTask and SingleInstance) though I cannot produce behavior like those exist in iOS and WP.
There is another post related to this question which may clarify my problem more.
The question exactly is, “Is it possible to produce iOS or WP application behavior in Android anyway?”
So essentially, once a "session" expires, no matter what the user tries to do, you want them to be redirected to a login activity, yes?
Assuming you have a method you can call which tells you whether or not a session has expired, why no simply check that method in onResume() etc. and if the session has expired, redirect the user to the login Activity?
There's an answer here about the application state that may interest you:
Checking if an Android application is running in the background
With Application, you get the onCreate and you can put some logic here.
So yeah, it's not as straight forward as in iOS but it's doable.
If it's just a session state, create a base activity that check against the session state
and inherit all your activities from it.
You can close all your activties by using the Android SDK before going to the login page or... lock the back button.