I have an Android app with 2 primary activities. When the app starts from scratch, both activities start and run just fine. Something like: A -> B. Activity A does all of the initialization needed for both A & B. All of my local testing on real hardware and emulator, A is always created (onCreate) before B is created.
However, on my app's crash report, I see an exception which can only be explained by B being started without or before A. Is this possible? Will Android create an internal Activity without creating the other activities for my app (B without A)? Is the order of Activity creation guaranteed (A then B)? How would I re-create either of these scenarios using the emulator or real hardware?
I can easily move my initialization code to work regardless of which Activity is started first, BUT I wanted to learn how to reproduce and test before making changes. I looked through the documentation but it didn't really help.
Here is the code that starts task B when user presses "play" button:
private void handlePlayTouch()
{
Intent intent = new Intent(getApplicationContext(), PlayActivity.class);
startActivity(intent);
}
After you started Activity B, you press home button and make your application in the background. The system would kill your application if the free memory is very low. If you tried to switch to your application after your application killed, the system would try to restore your application and activity B without create A first.
You can use DDMMS's Devices view to manually stop your application, there's a red "stop process" button.Make sure that you should make your application in the background.
In your case, I suggest you using a single activity. In the on create, you can prepare everything and then do what you need. If you would like to be sure that something will be executed only when something else is finished, use AsyncTasks.
In doInBackground => do the initialisation and onPostExecute, do what you have to do after.
The onPostExecute will bee executed only when the doInBackground has finished.
http://developer.android.com/reference/android/os/AsyncTask.html
EDIT:
Your structure is not respecting a good programming practice in Android, but if it is mandatory for you to keep this structure, you should at least use "unkillable" services for the activity A. This will make your code harder to destroy as a simple activity when your app will be put on the background, but there is still a chance to be destroyed.
To understand your problem, see the android activity life cycle:
For the services using, see:
http://developer.android.com/reference/android/app/Service.html
http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/
Related
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();
Scenario:
An Android app has an Activity with a Fragment.
The user sends the app to the background by pressing the home key.
Two hours pass, the Android OS kills the process to free up resources.
The user switches back to the app through the Recent Apps List.
The onCreate method of the Activity will now find the existing Fragment by using fragmentManager.findFragmentByTag()* as best practice cites. Yet, adding this old fragment to the activity will not make the fragment render. I'm unsure if I'm doing something wrong, or this is simply not a supported use case for reusing old fragments.
Must I implement special handling of this scenario (i.e. new up the Fragment instead of reusing the old)? If so, what is the best practice of detecting that the process has been killed and relaunched in onCreate?
edit 1: *) I am testing this by using DDMS to kill the process. This might not emulate the OS' way terminating a process correctly, as for instance onDestroy() is not called. Does anoyone know if the old fragments are disposed from the FragmentManager when onDestroy() is invoked by the OS? If this is the case, this question is moot.
No, You can't reuse a Fragment once the process is killed. Once the process is killed, you app no longer exists on Android main thread, hence a new instance of the activity has to be launched.
Your app starts with an your main activity as in Manifest file, and loads corresponding views and fragments. Please go through the Activity Lifecycle of the Android, to know more about it.
This teaches you how to maintain your activity run in background and when not in use:http://developer.android.com/training/basics/activity-lifecycle/index.html
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
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();
Ever since I added a new Class to my Android app (specifically, a sqlite helper class) may app wants to relaunch after I press the home button. Before adding the class, the app would multitask as expected.
I am stumped. It seems onDestroy is called every time the app goes into the background.
Any tips or thoughts as to why this would happen?
This is by design. Please refer to Android activity lifecycle for more info when/how your activity could be destroyed. Basically, as soon as your app goes into background, your activity can be killed at any moment.
If you want to continue execution, you need to create a Service that represents a long-running components in Android architecture.
It turned out I had android:finishOnCloseSystemDialogs="true" in the manifest file.