How to force Android to trigger activity kill - android

I am having an issue that's closely related to
support FragmentPagerAdapter holds reference to old fragments
and ViewPager and fragments — what's the right way to store fragment's state?
Anyway, my problem is that my application crashes on this one activity when it gets recreated after the system kills it. As it's a pretty heavy activity and I'm debugging to implement fixes, I need to trigger the "Activity killed by android system".
Right now, I am doing "Open 20 other apps, and then hope that my app gets killed before reopening it".
Is there any better way?
PS: I have tried killing it manually (force killing) from app information. It doesn't work, as my application gets recreated from my home screen

Actually I found an answer...
In developers settings, all the way down, look for
App -> Do not keep activities
Tick it, then launch your activity, leave it using homescreen, launch any other app (gallery or whatever), and then when you relaunch your app, it will have been killed by the android system

Calling the finish() method should work.
If you are inside of the context of the activity then simply call finish();
If you are outside of the context. Then pass the context of the activity and call
activity.finish();

Related

How an Activity is killed by Android?

As we know Android would kill a paused Activity in some conditions. And there is a FIFO back stack of Activities.
My questions are as follows:
How Android kills an Activity without pulling it from the back stack (it might affect the top active Activity)
After killing it, what things are released from this Activity? And can I still get this Activity's instance?
Android does not kill Activities "separately", it kills the whole app process with all Activities.
The only way to get an Activity killed by the system is to set Don't keep Activities flag in device's Developer Options. However this option is just for development, not for applications in release.
Activity can't be killed but Os can kill the whole application. In this case you can try finish()/finishActivity()/context.finish() to finish the activity. While you finish an activity backpress will not return to the previous activity.
System can't kill activity, it can call the whole app.
And when it kills the whole app, it doesn't call any method from activity (onStop(), onDestroy(), etc)
Finally, you can't get activity instance.

Android simulate temporary Activity destruction?

Is there a way to simulate an Activity being "temporarily" destroyed (as described in the Activity.onDestroy documentation)?
Perform any final cleanup before an activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
It appears this is happening to my App on some devices. After the "temporary" onDestroy, the Activity gets later gets an onResume, which isn't handled properly by my code (and, I would like to test and correct this).
In Developer Options in the phone's settings, near the bottom of the list, you can turn on "Don't keep Activities". When you press the home button, the system will destroy your Activity sort-of mimicking a low-memory situation. When you re-open your application, your activity will be re-created with a savedInstanceState bundle.
To enable Developer Options, go to 'Settings -> About phone' and click on the Build number 7 times quickly.
Edit: if this doesn't reproduce your problem, you can also try force-closing your app from ddms and re-opening it. This should work too.

Prevent activity from being destroyed as long as possible

I have an app, a single activity app with fragments in it.
The usual use case for this app is, that you start it and put the phone away and every now and then, you get back to the phone and insert some data... It's a logging app, you are doing something and insert your results into the app...
I have the problem, that every now and then, my activity get's destroyed and is recreated with an empty bundle... (Most of the time this is not the case, but every now and then this happens...). My app sometimes starts a service, even this service is killed in this case...
This means, that the system has killed my app, does it? How can I avoid this?
I need to keep the user data and the current top fragments... And they are saved to the bundle and everything works as long as their states and the data get saved...
Btw., my activity is always the TOP ACTIVITY, only that the screen turns off often... I just want to keep my activity alive as long as possible until the user leaves it with the back button... Or to save the state reliably
IMPORTANT NOTE
onSaveInstance does not always work (it's not part of the lifecycle and therefore not guaranteed to be called)... it only works most of the time... I need a way to that works always... If android kills my app...
don't keep your app in memory
You don't want to block Android from killing your app. What you want is to restore your app's state properly. Then the user will never notice the app has been destroyed and the user still gets the benefit of an app that was destroyed when not in use.
If you really want this use a wakelock. This will drain your users battery so I think twice before implementing this... Info at How do I prevent an Android device from going to sleep programmatically?
onSaveInstanceState explained
To do so check what information is needed in the bundle and persist that information with the onSaveInstanceState(bundle:Bundle) method so you can reuse it in onCreate(sameBundle:Bundle).
More information available from Google documentation at Save your Activity state and Restore your Activity State.
About Android Activity lifecycle
As stated by #prom85 in the comments below it's not guaranteed that the onSaveInstanceState method will be called because it's not part of the lifecycle. Workaround for this is using the onPause lifecycle hook to ensure your data is stored.
More information at Android: onSaveInstanceState not being called from activity
I had a similar problem, I arrived at this post while searching for a solution, you have to play with the manifest to achieve this and also understand what exactly activity is, in Android eco system,
In Android activity is a task which has a pre defined work.
I dig a lot in the documentation, I found that, we can configure activity in two ways,
Persistent
non persistent
if you mention for the activity in the manifest as
android:persistent="true"
and run the below use case
Start the APP
Press back or home button
you select the activity in the back stack again to bring it to front
Activity enters start -> pause -> stop - > resume , it does not get into onDestroy method.
if do not mention
android:persistent="true"
for the same use case
Activity enters start -> pause -> stop -> destroy, and if you select the activity from the back stack
Activity enters resume->create->start
If you want to run a service/task on activity start which keeps running when the app is in back stack, then you have to start that in the onCreate method, and kill them onDestroy by specifying your activity as persistent in manifest.
I hope my above solution might help others who arrive here for the same problem

pressing home button and access app again from app icon call onCreate?

I have an offline-online application, i found a strange issue in it, may be it is not, but i did'nt understand about it..
App requirement is that, if internet is available, even from starting app or from resuming, i call webservices and store data in sqlite, otherwise app stays in offline mode,
I have 2 activities, second activity contains an id, that i passes through intent (that point is important),
My Problem:
if i am in second activity, and internet is running, and i press home button , then this 2nd activity pauses, then stop which is a default behavior in android, i goto settings, turn wifi off, then press app icon again to get back in my app, here i got confused, i expect that my app now will be in onResume, but when i see in logcat its onCreated called and app
crashes, nullPointerException occurs, because this 2nd activity does not have that id, i passed through intent..
Note:
If i use recent app button to go to "settings", then come back again after turing wifi off, and repeat all this behavior, then working fine, its onResumes called not oncreate..
My Question
Why it is going in onCreate while i my expectation is to be onResume while i came back from app icon?
The NPE reason is clear, your second activity doesn't have the value and it crashes.
Why do you get different behavior then!?
It's because the launching intents are different. When you "task switch" Android is merely stopping your app but leaving it there (no guarantee) in case you want to switch back.
Going home (with home) is a clear indication that you want to leave the app, and although it will remain in memory and cached (as long as there is available memory), going back through the launcher (or App Icon as you call it) fires the LAUNCHER category (which goes to your Activity 1 first).
Take a look at this StackOverflow question (and answer) to better understand the consequences.
In any case, your problem is that your app must always be designed to resume in an inconsistent state and be able to recover. Android will kill your references, will destroy your variables and most likely send your app to hell overnight even if you have it running… if the phone goes on standby, chances are processes that aren't doing anything will be paused/stopped and likely killed.
Re-design your app so this is not a problem.
You say:
"I have 2 activities, second activity contains an id, that i passes
through intent (that point is important),"
Well, why not make it easier and have ONE activity and TWO fragments? Then use Fragment Arguments to pass the value?
Or why not store the value in the preferences and/or a local database and recover it during onCreate?
And also why not make it so that if Activity 2 doesn't have a value, it calls Activity 1 and closes itself (better than a crash, huh?).
Etc.
As you can see there are multiple things you should consider. All in all, never trust that your app will be alive, because it won't.
Once your activity's onStop gets called it's susceptible to be killed by the android system to collect resources for other apps which is what i think happened in your case.If it is killed, android will obviously call OnCreate when you get back to the activity.Check this for clarification. For experimenting you can try opening more than one apps from your recent apps and then return to your app. It may crash there too now.
You stated that you can see that the activitiy is stopped (onStop) if you go to the settings. That is the behaviour shown in the Android activity lifecycle. The counterpart for onStop is onCreate. So it does what the documentation tells us. Btw activities are paused if they are visible in some way and get stopped if they are not visible anymore. This would explain why your activity get paused. For further information read Managing the Activity Lifecycle. You can find a whole picture of the lifecycle here.
This type of behaviour can be seen when you change some system configurations like font type,font size or language. But turning wifi on/off won't destroy the app and recreate it again. Check http://developer.android.com/guide/topics/manifest/activity-element.html#config for more information

how to force android system to recycle all background activities?

Is there API or commands to force Android system to recycle all background activities no matter there is enough resource or not? And how to check all the activities' status to check that the activity is actually killed?
There is an API called killBackgroundProcesses(), but this API is killed the whole process, I am wondering how to only kill some activities without killing the whole process.
As the android dev guide page says below, I am looking for the first way.
activity lifecycle
If an activity is paused or stopped, the system can drop the activity
from memory by either asking it to finish, or simply killing its
process.
Yes, there is a way:
Settings -> Developer options -> Apps -> Don't keep activities
Check that box, and you are good to go.
Cheers.
I don't think so Android gives you the information of Activities are in background (i.e in Paused or Stopped State). Even if Activity Stack as well will give you the access of activity at Top.
Possible Solutions :
1. If at all you want to destroy the service , better to call finish() after startActivity() method.
2. If you want to periodically destroy all the background activities. You should implement your own activity stack. Which does pushToStack() on start of new activity and popFromStack() and then activity.finish();

Categories

Resources