Keep app alive when in background? - android

What code is required to keep an app live when it is "pushed" to the background?
My app USED to behave this way. If a user multitasked or hit home, my app would minimise, and they could later return to it. Now, and I have no idea what change I made to cause this, my app is closed by the Android system whenever it is minimised.
I have checked memory, and it doesn't seem to be an issue. My app is actually using LESS memory now than previously.
When the app is minimised and closed, OnPause and OnStop are being called for the current activity, but onSaveInstanceState is not.
SOLVED: It was caused by android:noHistory="true" in my manafest

Related

OnCreate is called multiply when app is started from Play Store App first and then from home screen

It occurred to me that under some circumstances our app seems to be restarted from scratch after being backgrounded. I managed to track to issue down to MainActivity.OnCreate being called multiply under the following circumstances
App is installed from APK and then ran from the installer, after backgrounding the app and starting it from the home screen it's reset to scratch
This behavior persists until the app is killed and then restarted from the home screen
App is run from Google Play app, after backgrounding the app and starting it from the home screen it's reset to scratch
If the app is backgrounded and then started from Play Store it's started correctly
App is run from home screen, after backgrounding the app and starting it from Google Play it's reset to scratch
When the app is foregrounded from the same launcher it has been started initially, OnCreate is not called again. There is at least one question reporting a similar behavior, unfortunately there is no answer providing a solution for the behavior.
When MainActivity.OnCreate is called, the instance of MainActivity seems to be a different instance than the initial one, since private members that are set in OnCreate are null when I'm trying to log them, anyway, the application context does not seem to be recreated from scratch, because AppCenter seems to be initialized right away on the second run, Xamarin.Forms starts up way quicker and static variables keep their values.
Is there any way to prevent this behavior and just keep a single instance of MainActivity active?
Congratulations! You've been bit by a long-standing, nasty Android bug which has been around since the dawn of time and is still broken, even though countless issues have been opened about it and the behaviour is reproducible and well-documented.
See the following:
https://issuetracker.google.com/issues/36907463
https://issuetracker.google.com/issues/36941942
https://issuetracker.google.com/issues/64108432
Re-launch of Activity on Home button, but...only the first time
App restarts rather than resumes
In September 2019, one of these issues was marked "fixed" with this comment:
Thanks for reporting this issue. The issue has been fixed and it will
become available in a future Android release.
So hopefully we will no longer be seeing this in Android Z ;-)
There is a workaround documented in my answer to
Re-launch of Activity on Home button, but...only the first time
in your android manifest set on the activity tag
android:launchMode="singleTop"
It will have consequences on how you handle notifications, and in some cases onActivityResult

Android: App screenshot preview in task list is blank?

In Android when you hold down the home button you can bring up a task list of your recent apps. And each "card" in the task list should have a preview of the app. However, this time I opened the task list and the previews were blank (except for the app title).
I had the phone Settings in the task list and every time I would tap on the task and try to open it in would close immediately.
I also had this app I was developing and when I tapped on the task to open the app my RecyclerView wasn't showing anything, when it should be.
I also was playing AngryBirds 2, so was it that Android had silently killed those apps for memory? If so, does onCreate() of the killed apps get called again when this happens?
Edit: I just noticed if you close an app too quickly when it's transitioning to an Activity you can get a blank preview.
Edit 2: So to answer my question, after referencing the Activity lifecycle diagram this is what I found. When another application needs memory, the app's process will be killed and when the user navigates back to the app, onCreate() will be called again. However, that doesn't explain why I couldn't reopen the Settings. And I have no idea how to reproduce this weird behavior!
Ok after some debugging, I found out that Android did indeed kill my app because it needed memory. When you resume to your app however, onCreate will be called with a savedInstanceState that is NOT null. I had some logic that required savedInstanceState to be null and therefore my RecyclerView wasn't populated.
To recreate this scenario of Android killing my app I had to open a ton of apps lol. Is there way I can reproduce Android killing my app without opening all those apps? Hm...

Android App Icon intent category seems inconsistent

Clicking my app icon will sometimes take me to the launcher activity, but other times it will resume the activity where it left off (emulates the behavior of clicking the application in recents).
I've read (can't find concrete docs about this, other than a one off post from 3 years ago by Diane Hackborn) that after about half an hour, the OS will make sure that when you click the app icon, it will relaunch the app, but sometimes it seems to do this directly after I exit the application (with the home button, not the back button as that will call finish on the activity).
Why is this?
Is there any way to force the launcher activity in the Android OS without killing the app first then restarting it? I need to test how my app handles the launcher activity after the application may already be running.
Android will free up memory whenever it feels necessary. For that, it will kill inactive apps. If your app goes to background, at some point Android will probably kill it. Matter of time.
You can kill your app, or you can make it kill itself when it goes to background. No more options.
in order to make your app kill itself, you should override the onPause() method (which is always called when the app goes to background) and add in it a call to onDestroy().

Is it fine if I see my application from Settings App in the emulator has Force Close option enabled even tough I have come out of my application?

I have written a simple database program in android. It runs fine, there is no force close error. But I checked from my application from Settings App I see the Force Close option enabled, which implies that my application is still running in the background, even though I have completely came out from my application to the home screen by pressing back key. And moreover I am not using any services, alarm or broadcast things.
Can some one please guide me what may be the probable reason?. Or is it okay? Or will it crash if I put it on device?
Can some one please guide me what may be the probable reason?. Or is it okay? Or will it crash if I put it on device?
Your application is alive until Android OS needs more memory and destroys it. What I have understood does Android start destroying activities before killing the whole application. This means that your application can be alive even if you have finished your activities.
Do not worry about this; Android OS is handling this extremely well.

How to simulate killing activity to conserve memory?

Android doc say:
"When the system, rather than the user, shuts down an activity to conserve memory, ... "
But how to simulate this situation?I want to debug the onRestoreInstanceState(Bundle) method,but don't know how to.
You can't do it in an automated way b/c its completely non deterministic.
See my answer here: https://stackoverflow.com/a/15048112/909956 for details.
But good news is that all you need to do is just simulate calling onSaveInstanceState and you are indirectly testing this low memory situation.
onSaveInstanceState can be triggered by:
losing focus (by pressing home which in essence is like switching from your app to launcher app), launching another activity, pressing recents
changing orientation. this is the easier way if you are using an emulator
changing developer setting: goto developer options --> Apps --> Don't keep activities. This is best option if you are testing temporarily on an actual device.
I've used the "Don't keep activities" developer option to reproduce a crash that happened when an activity was killed due to memory pressure. You can find it in the Apps section of Settings->Developer Options.
It destroys every activity as soon as you leave it. E.g. if you press home to put your app in the background the current activity is destroyed. See https://stackoverflow.com/a/22402360/2833126 for more information.
There's two way to simulate the android killing process: using the setting "Don't keep activities" in developer settings or killing the app process by yourself.
To kill the process, open the activity you want to test, then press home button to send your app to background, and then, using the DDMS in Android Studio (Android Device Monitor), select the process and then stop the process (as seen in the image below). Your app was killed. Now, open your app again (accessing the list of open apps). Now you can test the killed state.
For the purposes of debugging onRestoreInstanceState(), just change the screen orientation ([Ctrl]-[F11] in the emulator). Your activity will be destroyed and recreated, and the onSaveInstanceState()/onRestoreInstanceState() pair will be invoked.
Use the SetAlwaysFinish app (works on a real device and in the emulator) or use the Google DevTools app (works in the emulator only).
These apps use the hidden AlwaysFinish setting of the ActivityManagerNative class to change the behavior of the OS and cause it to immediate unload every activity as soon as it's no longer in the foreground. This will reliably trigger the onSaveInstanceState and onRestoreInstanceState events.
See link below for more details:
http://bricolsoftconsulting.com/how-to-test-onsaveinstancestate-and-onrestoreinstancestate-on-a-real-device/
To debug onRestoreInstanceState you could do the following:
make sure you can debug application right after its start (calling android.os.Debug.waitForDebugger() from your constructor helps, it hangs your application until debugger is connected),
put you application in some state,
causally kill it from Settings->Apps,
causally switch back to it through Recent Apps button (it will still be in the list),
at this moment your application will be started anew and onRestoreInstanceState will be immediately called on the top activity.
Good answers here.
Now, residing in the distant future, using Instant Run in Android Studio will also trigger a save and restore when activities are restarted with code changes.
There's a decent solution for this in Android 6 and newer. See my answer here: Simulate killing of activity in emulator

Categories

Resources