How to emulate unloading of a background application by Android OS? - android

For testing purposes I need to easily reproduce a situation when Android system decides to save a state of and kill a background application, in the same manner as it normally does for memory optimization purposes. In fact, I need also to test the restoration process of such a removed process when a user switches back to it.
The straighforward approach would be to open the application and then open more other tasks trying to allocate as much resources as possible. That's too complicated and unreliable.
I've found this question on SO, but the answer implies simply killing the process, which seems not an equivalent, because there seems no means for further automatic restoring of the killed process with a saved state, when a user decides to switch back to the application. If I understand correctly, after such explicit killing the application, if started, will run from very beginning, not from a saved state. Please, correct me, if I'm wrong.
According to Android documentation, what I need is performed by ActivityManager.killBackgroundProcesses(packageName), but this is the programmatic way of doing the thing. Is there an utility which already provides the same option from UI?

If I understand correctly, after such explicit killing the application, if started, will run from very beginning, not from a saved state.
That depends on how the app is launched. If you mean from the launcher icon, yes. However, the user could return to you via the BACK button, or via the recent tasks list, depending upon circumstances, and those would return the user to the spot they left, not the "very beginning".
Is there an utility which already provides the same option from UI?
On an Android 4.0+ device, with your app in the background, open up the recent tasks list (long-press HOME or press the dedicated RECENTS affordance), and swipe your app off to the right. This appears to basically call killBackgroundProcesses() on that package name.
I have not tried this in an emulator, but probably it does the same thing.

Related

Why don't Android and iOS kill the process when the app is closed?

On Windows, MacOS and Linux, when an app is closed, the norm is that its process is also killed. This happens as default on Windows/ Linux, and on MacOS, it still seems like a good idea to press CMD+Q to kill the process when no app window is open.
On Android (and iOS too) when the app is backgrounded, its process still keeps living in the memory till the OS finds it necessary to push it out. The process can be killed but this step is not the default OS behaviour and is somewhat discouraged by the UX.
Why?
Update
Some of the replies do seem to suggest that there are potential benefits in keeping the app in memory. So a further follow up will be, why then main stream desktop OS(es) do not follow the same approach to reap all the same benefits?
Android is very good at managing its resources. It has a certain amount of memory (RAM) to work with, and it’ll happily allow apps to use as much as they need for best performance.
If RAM starts to get a bit short, and other apps and tasks need some, then the OS will quietly close one of the apps running in the background that you haven’t used for a while, and assign that app’s RAM to the new task.
As a result, apps can stay in memory for hours, days or potentially even weeks since you last used them. And this is fine. They’re not draining the battery or using other resources so there’s no downside; the upside is they will load much quicker when you need them, and load them right back to the place where you left off too.
(It’s also worth noting at this point that there’s really no benefit in keeping RAM free. RAM exists to be used, and using all of it at any given time—or virtually all of it at least—will ensure your phone or tablet runs smoother than if you try and keep some RAM free.)
With all this in mind, it becomes clear why closing apps can have a worse effect on Android than leaving them open.
Ref: androidtipsandhacks.com
Answering to your question update and agreeing with the already posted answers stating that keeping an app in memory may be better for battery and app resume/start up.
A mobile device is designed to be fully mobile, to be in your pocket or hand all the time, and connected to an electricity outlet just for charging, and usually nothing more. So, it must have a battery saving centric design.
A desktop is always connected to an outlet, so doesn't have the battery shortcomings and requirements of mobile devices.
About laptops, although they are portable, they are actually used most of the time also connected to an electricity outlet. The fact that they can be carried from one point to another doesn't make them comparable to mobile devices.
So, although desktop OS(s) now days have battery saving features tailored mostly for laptops, their design is focused with the fact that the host device will usually work connected to an electricity outlet, and they have never evolved to have a battery saving centric design, which is a "must have" requirement for mobile devices.
On the other hand, if you want to consider not the battery but the app resume/start up benefits, then actually such feature is already implemented in both types of OS(s), but in a very different way. For example in Windows you can minimize a program, this is the exact same thing as pressing the home button in Android. To close it you press the x button a the corner or the program's exit option, that would be like going to Android apps task manager (recent apps history) and killing the app.
Because some applications behavior relies on background services that can not work if the main process is killed. When you swipe off an application from the recents, you're not really killing the app, the background services are still there.
Imagine that you close Whatsapp and the OS thinks that it's a good idea to kill the entire process. You wouldn't recieve any message unless you re-launch the app.
According to documentation, there are 4 states of application process in android app.
Let's look at a few cases.
1. App has running Activity. User presses home button.
In this case app status will be moved from Foreground to Cached.
Cached state is used for providing better UX, when user switches between apps. Because opening a cached activity is much faster then restoring it from saved state.
2. App has running Activity and Service. User presses home button.
In this case app status will be moved from Foreground to Service.
Service state is used for processes which have some unimportant background job. In this case process is kept, because it has some background job to do. Of course you can move your Service to a separate process, but it is not a default behavior.
3. App has running Activity and foreground Service. User presses home button.
In this case app status will be moved from Foreground to Visible.
Visible state is used for processes, which are visible to user, but he doesn't interact with it directly. Foreground Service is used for doing important background job and keeps process at Visible state. Again UI and Background parts of app by default are placed in same process.

Why my app stop working?

I am developing a simple app that just play a white noise sound in background while I am doing other things.
It works very well when I switch to other apps ( like games, chrome browser, etc ) but sometimes ( for example when there are many chrome tab opened ) the white noise sound stop and I need to reload my app.
I am NOT using Services, is this the reason ?
Because your apps is getting killed by the system to give up resources for to other apps (games, chrome, etc). So you need to use a Service.
Here an excerpt from Processes and Application Life Cycle
for more details explanation:
An unusual and fundamental feature of Android is that an application
process's lifetime is not directly controlled by the application
itself. Instead, it is determined by the system through a combination
of the parts of the application that the system knows are running, how
important these things are to the user, and how much overall memory is
available in the system.
...
A cached process is one that is not currently needed, so the system is free to kill it as desired when memory is needed elsewhere. In a
normally behaving system, these are the only processes involved in
memory management: a well running system will have multiple cached
processes always available (for more efficient switching between
applications) and regularly kill the oldest ones as needed. Only in
very critical (and undesirable) situations will the system get to a
point where all cached processes are killed and it must start killing
service processes. These processes often hold one or more Activity
instances that are not currently visible to the user (the onStop()
method has been called and returned). Provided they implement their
Activity life-cycle correctly (see Activity for more details), when
the system kills such processes it will not impact the user's
experience when returning to that app: it can restore the previously
saved state when the associated activity is recreated in a new
process.
I think Services is What You are looking For.
A Service is an application component that can perform long-running
operations in the background, and it does not provide a user
interface.
For better chance of preventing OS to kill your app, you should use a
Foreground Service
following the official guide here: https://developer.android.com/guide/components/services.html#Foreground
Remember that there is no way to be certain that OS will never kill your app, because when RAM becomes really low it could kill every process indipendently from type, following his priority rules

Resume Back Kivy Application even if minimized (not closed) to recent activity

is there a way to resume back a Kivy application to most recent activity even if minimized? i mean when i am in the application ( a compiled application as .apk) and i want to open wifi for example or check other apps, my application closes and i need to restart it again by pressing on it again...so if i am in the middle of an operation in my application (a calculation or an e-mail composition) and i want to check another application ,all my operation would be cancelled if i do so and of course it is a terrible user experience...
The documentation here describes how to enable pause mode, such that your app will be resumed rather than restarted if you leave then open it again.
The main point is to add an on_pause method to your App class, and have it return True.
Note that you are never guaranteed to be able to unpause again (Android itself may kill paused apps if their memory is needed etc.), so you should also use this method to carry out any state saving you need. However, it's unlikely to be a problem for short task switches, and may rarely or never come up in newer devices with more resources.

Simulate killing of activity in emulator

I would like to test out onSaveInstanceState and onRestoreInstanceState for my app on the emulator.
I have found this, which says that we could simulate this during orientation change, but I'm storing some of my variables on the application level (subclass android.app.Application), so the orientation change does not wipe out the variables.
So my question is, how can I simulate the low memory situation thus killing of my activities?
Hope I've made myself clear. Thanks
You can pause your application (by pushing the Home button, simulating a call, whatever). Then kill the app's process through adb. Since the docs say that after onPause() returns your app can be killed without any further notice, this is a fair test.
If you don't want to go through the trouble of finding the pid of your app's process, you can use adb shell am kill com.example.package_name to kill your app's process. Make sure that the app is put in the background. The docs say that this command "kills only processes that are safe to kill and that will not impact the user experience." So you might want to launch a couple of other apps before trying this one.
There's a more solid solution for this in Android 6 and newer. I've used the following method successfully on Android 6, 7, and 8:
1) Open your app, go to the activity that you want to test restoring, and then leave it by pressing the Home button
2) Open the Settings app, go to System -> Developer Options, then tap on "Running Services"
3) Tap on "Show Cached Processes" at the top right, then find your app in the list, tap on it, and then tap the "Stop" button.
4) Use the recent apps list to return to your app. It should relaunch the whole app on the activity that you had previously left it from.
I've found this to be sufficient to fully kill the app, including any app delegate stuff and the C/C++ native code state, and then test relaunching it with a saved activity state... This effectively replicates what happens when the user leaves the app for a while and then the system kills it to save memory, battery, or whatever.
To test the onSaveInstanceState and onRestoreInstanceState events you can use the SetAlwaysFinish utility (see link below). It uses a hidden system setting called Always Finish to change the behavior of the Android system. With the Always Finish option enabled, the Android OS will immediately unload any activity that moves from the foreground to the background, triggering its onSaveInstanceState event. Then, when the system needs the activity again, it is forced to reload it triggering the onRestoreInstanceState event.
The advantage of this method compared to killing the process is that it's easier and you get finer control (activity level rather than process level).
See the blog post below for more details on the tool and how to use it:
http://bricolsoftconsulting.com/how-to-test-onsaveinstancestate-and-onrestoreinstancestate-on-a-real-device/
The Always Finish feature is also present in the emulator in the DevTools app under Development Settings > Immediately destroy activities. However, the DevTools app does not work outside of the emulator.
You can use the setting "Don't keep activities" in developer settings or kill 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.
Lets clarify your question.
But before we do that here is a fact about onSaveInstanceState - its gets called for various reasons such as:
orientation change
going from foreground to background (by clicking home or launching another activity or clicking recents)
system is under low memory
Now, if your question is "how can i simulate the calling of onSaveInstance for just testing purposes" then Theo and Ted's answer is correct. Both changing developer settings option or pressing home will result in onSaveInstance being called.
But so would just changing orientation (as you noted in your question) - which leads me to believe you might be asking "how can i simulate calling of onSaveInstance method when system is under low memory pressure"
The short answer to this question is there is no automated way to simulate low memory condition. The above mentioned techniques only simulate calling of the onSaveInstanceState method not low memory conditions per se
Couple of caveats here.
The first caveat to this is that under extreme conditions the kernel will "uncleanly" kill your process to claim memory - meaning onSaveInstanceState will never be called. In this situations testing onSaveInstanceState is moot. There isn't much you can do about this scenario but the good news is that its a very rare event esp. for foreground activities.
The second caveat is that ActivityManager can reclaim your activity's resource by "killing it cleanly" i.e. your onSaveInstance will get called. This happens to activities that are not in foreground (i.e. not visible to the user so already in stopped state) and the system is under memory pressure.
On this second caveat, again you can't simulate this condition automatically. It can be done if you start bunch of heavy duty activities manually and hope the ActivityManager is forced to recycle one of your activities.
The bigger point to remember here is that there is no need to simulate low memory condition. As long as you are simulating how onSaveInstanceState is called you are automatically testing the condition where it might be called for low memory situations. And the easiest way to trigger this method is to change orientation on the emulator (ctrl-f11). And if you are using an actual device to temporarily change the developer settings ("Don't keep activities")
From android doc, http://developer.android.com/reference/android/content/ComponentCallbacks.html#onLowMemory()
This is triggered by the system. I think you can set the device ram size lower during creating an android virtual device. (In Hardware, choose "Device ram size")
The simplest solution which works for me is just change the orientation of the device (you can do that regardless you're using AVD, Genymotion or any other emulator). By default system will recreate Activity by calling onDestory followed by onCreate.
Ensure Activity has not defined below attribute on AndroidManifest.xml
android:configChanges="orientation"

Why dont Android applications provide an "Exit" option?

Is there something in the Android developer guidelines that disuades developers from providing the option to "exit" (stop running) an application from within the application itself?
I love multitasking and all but it's not clear to me why:
the vast majority of apps don't have their own Exit functions and hence just keep running forever
don't give you a choice about running when you turn on the phone - they just do by default
Both of these things lead to memory usage constantly increasing and your device running with this performance burden all of the time despite the fact that you may only want certain apps to run some of the time.
Am I missing something?
Is there something in the Android
developer guidelines that disuadea
developers from providing the option
to "exit" (stop running) an
application from within the
application itself?
Yes. It is generally not needed, just as it is generally not needed to restart a Web server because some user with a browser decided (s)he is done with a Web app.
the vast majority of apps don't have
their own Exit functions and hence
just keep running forever
They don't keep running forever. Android will close things up as needed.
don't give you a choice about running
when you turn on the phone - they just
do by default
Those developers aren't paying attention to me.
Both of these things lead to memory
usage constantly increasing
Generally, it doesn't. If you find specific apps that do this, uninstall them.
and your device running with this
performance burden all of the time
Generally, it doesn't. If you find specific apps that do this, uninstall them.
Also, this question is a duplicate of this one.
"Both of these things lead to memory usage constantly increasing"
Which doesn't matter since Android apps are limited to a fixed amount of RAM. Freeing RAM won't give more RAM to other apps.
Essentially, there's no need for a quit button as long as the developer does a good job of designing their app. Android activities are stopped when they aren't visible and resources are needed elsewhere, so the are no longer consuming resources. You can read about the lifecycle here:
Here's a related question:
From Google's Android Application Fundamentals page:
Shutting down components
A content provider is active only while it's responding to a request from a ContentResolver. And a broadcast receiver is active only while it's responding to a broadcast message. So there's no need to explicitly shut down these components.
Activities, on the other hand, provide the user interface. They're in a long-running conversation with the user and may remain active, even when idle, as long as the conversation continues. Similarly, services may also remain running for a long time. So Android has methods to shut down activities and services in an orderly way:
An activity can be shut down by calling its finish() method. One activity can shut down another activity (one it started with startActivityForResult()) by calling finishActivity().
A service can be stopped by calling its stopSelf() method, or by calling Context.stopService().
Components might also be shut down by the system when they are no longer being used or when Android must reclaim memory for more active components. A later section, Component Lifecycles, discusses this possibility and its ramifications in more detail.
So it seems like Content Providers and Broadcast receivers should never be explicitly shut down, as they are inert while not handling their specific events.
As for Activities, I would argue in favor of having an end to it, but in certain cases. If your app has a finite state in which the user is done using it, why keep it alive until GC gets it? The activity manager still needs to keep track of that Activity while the user has finished their task. My best example for this is the Calculator. You open it, you have it solve a problem for you, and then you close it. If the onCreate function is so expensive that it's more effective to do onCreate once and then onRestart whenever the user moseys back to your application then you're probably doing something wrong. Maybe I'm misinterpreting how Android handles Activities, and if so I'm always interested in learning more :)
It all comes back to the answer that users want total control of their running and auto-start list and what they do and don't want installed, example: google maps, etc etc. there are no two ways about this.

Categories

Resources