Simulate killing of activity in emulator - android

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"

Related

Is there a method inside android to know when the system is going to kill my app?

We have one very difficult to reproduce problem with an app. The use case is as follows:
User opens app
User leaves app in background
User openes 5 to 7 more apps
System kills our app
When user tries to resume app, app crashes due to NullPointerException
I was trying to use console log with Application class method onTrimMemory() and onLowMemory() but this methods are not being called. Is there any method or callback I can be listening to know when android system will kill my app due to many more apps being opened and in that case for me to do something?
You can save whatever states you need in onSaveInstanceState() and restore them in onRestoreInstanceState(). onDestroy() is what the system will most often call to clear room while your Application is in the background, but it is not guaranteed to be called, so it is better to have already saved your states in onSaveInstanceState().
Is there any method or callback I can be listening to know when android system will kill my app due to many more apps being opened and in that case for me to do something?
Not really. Depending on circumstances, onDestroy() of running activities and services will be called.
We have one very difficult to reproduce problem with an app
That should be reproducible in a matter of seconds:
Run your app.
Switch to another app.
Kill your app's process from your IDE (e.g., "Terminate Application" toolbar button in "Android Monitor" tool window).
Try returning to your app from the overview screen (a.k.a., recent-tasks list)

Confused about this Android Activity life cycle scenario - OnCreate gets called whenever app goes back to foreground

To make things as simple and easy to follow I created a new empty project in Android Studio with only one MainActivity and Hello World text. This could not by any means be a consuming app. I also did override all the important life-cycle methods like onCreate ,onStart, onResume, onPause, onSaveInstanceState, onStop, onDestroy and logged them to see what is happening.
So here is what I am experiencing (in each step the list of life-cycle callbacks is printed)
After app/activity launches (expected behavior)
onCreate onStart onResume
After I press home button / app goes in background (expected behavior)
onPause onSaveInstanceState onStop
After I immediately return / app goes in foreground (expected behavior)
onStart onResume
After I press home button (app goes in background) and I open another app like Facebook and immediately return back to my app I expect it to resume, but instead onCreate gets called.
onCreate onStart onRestoreInstanceState onResume
I find this really strange because I am not low on memory on my device and I have basically empty activity. Is there some flag I can set in the manifest or any solution that will not recreate my activity when I return to it ?
Please don't suggest I save and restore state using onSaveInstanceState and onRestoreInstanceState, I am specifically interested why onCreate is called when I move my app back in foreground. I've done many apps in the past and I don't remember having this issue before with activities being destroyed so early.
I open another app like Facebook and immediately return back to my app I expect it to resume, but instead onCreate gets called
Apparently, Android terminated your process, either of its own volition to free up system RAM or at the behest of some other app (e.g., task manager). This may also be device-specific, as device manufacturers can tweak how this stuff works, from what I can tell.
I find this really strange because I am not low on memory on my device
Perhaps Android or the task manager disagreed with you. Perhaps your means of determining free memory isn't the same as what the out-of-memory killer uses. Also, bear in mind that Facebook uses some techniques that cause them to use an outsize amount of RAM for their process, so they will cause more of this sort of thing than will a leaner app.
Is there some flag I can set in the manifest or any solution that will not recreate my activity when I return to it ?
No.
That being said, there are a variety of factors that the out-of-memory killer will use to determine what process(es) to terminate to free up memory, including:
process importance (are you in the foreground? do you have a service running?)
process age
process working set size (i.e., memory usage)
Please don't suggest I save and restore state using onSaveInstanceState and onRestoreInstanceState
I would suggest to all Android developers that they save and restore instance state using onSaveInstanceState() and onRestoreInstanceState(). That helps with configuration changes as well as these sorts of process termination scenarios.
I've done many apps in the past and I don't remember having this issue before with activities being destroyed so early.
Perhaps you did not test them on this device, or on this device and OS version (if you got an upgrade). Perhaps you did not test them in this scenario (e.g., launching Facebook). Perhaps you did not test them with the other apps you have running that might be affecting matters. Since you wrote those other apps, presumably you can re-run your tests using those apps, for more of an apples-to-apples comparison.
You can (and should) make this happen for testing by turning on the "don't keep activities" developer option. You cannot prevent it from happening. This can always happen, and you must handle it gracefully.
Please don't suggest I save and restore state using onSaveInstanceState and onRestoreInstanceState
That's what you have to do if you want your app to work reliably.
The android lifecycle guarantees some things and provides no guarantees about others. It's guaranteed that if your activity was destroyed, onCreate() will be called before onStart() and onStart() before onResume().
However, in most cases there is no guarantee that your activity will NOT be destroyed once it goes into the background. The reasons are not fully spelled out because this gives google (and individual android distributions) the freedom to modify such things in the future. Part of the downside of having no such guarantee means that just because your activity did not get destroyed in the past, does not mean that in a different version of android, different device, or different circumstance, that it will not get destroyed in the present.
If you must know the exact reason why, I would suggest monitoring the log output very closely, it may contain some clue. But keep in mind that android does not intend for the developer to try to avoid this, only to resume from where you left off when the activity is re-created.

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.

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

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.

Simulating activity death in Android

We know that when the system runs out of resources, an activity in background serializes its state and gets killed by the OS. When we resume it, the OS recovers the activity state by savedInstanceState passed to onCreate method. Considering we are responsible for handling what is going to be serialized/recovered, I'd like to have my activity killed in order to test the code I created for recovering. How can I achieve that? Forcing the application to be killed through the applications menu doesn't help.
Rotate your device (or emulator). Android saves, destroys, and re-creates the activity in the new orientation.
Download a task manager that kills the process in a less destructive way than "Force stop" in "Manage applications" settings. Example: GO task manager.
The task manager will kill the app (and the debug) but somehow not the activity stack (don't know why).
When you'll relaunch the app again, onCreate will be invoked with the last saved bundle/state.
The disadvantage of this solution, compared to Darrell's, is that you cannot debug it.
The advantage of this solution, compared to Darrell's, is that it is more close to real life scenario.
You can kill it from Eclipse also.
Go to the Android view. YOu should see the list of processes in the Devices tab.
Click on your process and then click the little "STOP" button.
Instant death!
FYI you can also attach the debugger this way by clicking on the little green bug

Categories

Resources