Often when I open my Android app from either my Home screen shortcut or from the apps menu it restarts the main activity.
How can I prevent this behavior and make it bring the existing instance to the foreground if there is one running?
I've searched quite a bit to no avail. It would seem as though most others are not having this problem?
Thanks!
You can never assume that Android retains the state of your app after you move away from it - because of a low memory situation, it may have removed it from memory.
Your best bet is to store the current state (including the current activity) in your SharedPreferences, and in your main activity (the one marked as LAUNCHER in your manifest), you check the shared preferences and go to the activity marked there. You can also use the SharedPreferences to store other information about the activity, i.e. you can use it to fill out text fields and other things with whatever values they had when the user left.
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.
I found and read a lot of articles talking about global variables in Android, some of them suggests using an subclass of Application + declare it in the manifest file as a glbal variable container.
But some articles mentioned that This class could also be killed when system memory gets low, is this correct?
So, is it 100% reliable to use an Application subclass as a global variable container? And could somebody give me a link to some documents explaining the life cycle of an application in Android (not activity)?
EDIT:
Thanks for the answers, I think I need to explain a bit more of my question.
The situation is, I just want to share a global String variable, Activity A modifies it, and activity B reads it.
When B is currently visible and user receives a call,
If A and B are killed but Application keep untouched (is this what Google calls an empty process?), I'm OK with it.
If A, B, and Application class are all killed and when user come back my app gets a clean start, I'm OK with it.
Which I'm not OK with it is, everything was killed including the Application class, when user come back my app doesn't start fresh, I mean, it starts from Activity B, will this happen? then should I start A manually or let Application class to do the initiation? none of these ideas looks good to me...
The answer is both "YES" and "NO" - the Application class can be used as a "global variable container" in that all activities and classes can rely on it.
However, you cannot rely on the Application class (or any other class) to persist indefinitely. In other words, if the user answers their phone, your application could be destroyed and then re-created when the user completes the call and returns to your app. So, you definitely cannot rely on it to persist data, but you can rely on it to provide global access to data when you app is active.
This is the Android documentation:
http://developer.android.com/training/basics/activity-lifecycle/index.html
This is a really good post on it - read the SECOND highest voted response, in addition to the "accepted" response:
Using the Android Application class to persist data
It explains pretty clearly how your app can be killed/destroyed whether you expect it or not.
EDIT:
To clarify, if you have a variable (call it "myVar") in the Application class and a user sets it in Activity A, then proceeds to Activity B, Activity B will be able to read the change.
If Android "destroys" the application class, which can occur anytime the user is not in your app (and in rare instances even if they are...), the app will be reconstructed so that the Activity Stack is still valid but "myVar" is not set, unless you persist the data.
In other words, Android will recreate the Application class and Activity B, but there is no guarantee that it will recreate Activity A until the user does something to destroy Activity B. Also, it will certainly not "replay" the user actions in Activity A in order to recreate the app state, and in your case that means "myVar" is not reliable.
If you read the references provided, you will see that this is the case (and also I have tested it).
EDIT 2:
To persist data, consider SQLite (which is pretty complicated and there are many references) or SharedPreferences:
How to use SharedPreferences in Android to store, fetch and edit values
This class could also be killed when system memory gets low, is this correct?
Yes.
So, is it 100% reliable to use an Application subclass as a global
variable container?
If you want to use it to pass values it is not reliable.
why?
EDIT:
Which I'm not OK with it is, everything was killed including the
Application class, when user come back my app doesn't start fresh, I
mean, it starts from Activity B, will this happen?
yes. It is possible that you set a value in your application from activity A and then when you are in Activity B user leaves your app and after a while android kills your process. then user comes back wants to look at your app. android again recreates application and activity B but not Activity A and instead of fill the application variable with what has passed Activity A to it, it recreates it from default initialization. So simply you missed what has passed or set by Activity A.
Don’t Store Data in the Application Object
Hi guys as the title says I am trying to keep my application alive so to speak when the phone locks.
In detail my app would be open and running fine if I leave my phone alone for a while and unlock it my application is frozen and can't do anything. Now this only happens on some devices for some weird reason but I am wondering is there a way to manage these kind of things?
Thanks
Implement the onPause and onStop on your activity.....
To see if they are being called....
I have been trying to overcome this kind of issue in a few apps as well. My research points me here: Android - Activity Lifecycle as it states this:
However, if the system destroys the activity due to system constraints (rather than normal app behavior), then although the actual Activity instance is gone, the system remembers that it existed such that if the user navigates back to it, the system creates a new instance of the activity using a set of saved data that describes the state of the activity when it was destroyed. The saved data that the system uses to restore the previous state is called the instance state and is a collection of key-value pairs stored in a Bundle object.
So, we need to be leveraging the savedInstanceState Bundle for cleanly packing and unpacking each Activity and Fragment.
I'll work on an example for you ASAP.
How can I have my Android app resume where it last was, i.e. the Activity in view, etc.? If I am showing an Activity and press the Home button and then launch my app again it returns to the startup activity. I'd like it to work like an iPhone app where it suspends in place and resumes back to where the user last was.
Thank you.
You may need to set android:alwaysRetainTaskState="true" for your root activity in the manifest. From the documentation:
Whether or not the state of the task
that the activity is in will always be
maintained by the system — "true" if
it will be, and "false" if the system
is allowed to reset the task to its
initial state in certain situations.
The default value is "false". This
attribute is meaningful only for the
root activity of a task; it's ignored
for all other activities.
Normally,
the system clears a task (removes all
activities from the stack above the
root activity) in certain situations
when the user re-selects that task
from the home screen. Typically, this
is done if the user hasn't visited the
task for a certain amount of time,
such as 30 minutes.
However, when this
attribute is "true", users will always
return to the task in its last state,
regardless of how they get there. This
is useful, for example, in an
application like the web browser where
there is a lot of state (such as
multiple open tabs) that users would
not like to lose.
Be sure to save any information you want in your onPause method and check that information in onResume. This will let the app reload any information that was communicated. Some widgets keep state but others don't.
Additionally when an an activity is killed it's onSaveInstanceState method is called. So anything that needs to be stored to persistent memory should be done there.
Although i'm working with Mono for Android i had a similar question.
After some time researching on the web you can setup an Activity to be created using the singleton pattern. This will cause your app to only create one instance and - if you go back to the activity - this will load the last state of that activity for you.
You can do this by configuring the activity with the
android:alwaysRetainTaskState="true"
and the
android:launchMode="singleTask" //(preffered, or "singleInstance")
properties.
Singletask is the best since singleInstance is more suitable for single-activity-based apps.
In my case setting the launchmode made this baby rock as i wanted but i don't know if this is a Mono for Android or Android issue at the root..
Be aware: you will need to create an initialize method or something alike if you'd like to create a clean/fresh/new instance of the activity at some point.
I use my Android app's application Context as a storage area for "current state" information for my app.
I'm finding that in the field, there are cases when this information goes away on some people's devices causing various NullPointerExceptions since I expect the data to be there when the app resumes and starts rebuilding the necessary activities.
This usually happens when the user hits "Home", does something else, then eventually wanders back into the app - it attempts to go back to where it was before, but the application Context has mysteriously lost all its previously-saved state information (in my case, a few integers and a few Strings).
I know this is a very vague question, but are there any cases (other than the user using "back" to back completely out of the application) where the application Context gets completely destroyed even though the application is not terminated?
Is there a better way to maintain persistent state information?
Yes, it is possible for the Application to be killed and restarted if the user leaves the application for a while. You might want to read this section on processes and lifecycles.
You should find an appropriate place to save state to a persistent store. If its just a few integers and strings, it should be pretty simple to save them to shared preferences as they change. See data storage - shared preferences.