So I have two activites where I can switch between. Let's call them ActivityA and ActivityB.
Now if I'm in ActivityB and it somehow crashes and I start my App again it should appear the ActivityB and not A.
I thought of SharedPreferences(I already used it for the switching) and savedInstanceState, but can the last one handle with the savedInstanceState of other activites or just by its own?
Can I somehow tell ActivityA to look if there is already an instance of ActivityB and if so ro start it immediately?
When an app starts, Android always runs whichever activity it is told to (as defined in the manifest) - which can work to your advantage. You should be able to create a splash activity that determines what the last activity was (via tracking, sharedPrefs or perhaps savedInstanceState - I haven't mucked with the latter much), and then launch the appropriate activity before finish();-ing the splash activity.
Make sure the splash looks decent though - add in a handler that will keep it up for at least 1500-2000ms.
Related
I ran into a similar issue with the recent list in that there seem to a handful of conditions where an app will be completely destroyed but some other process will launch the app cold from the last activity that was being used. Since my app has a state that is built up over several designated activities I need to prevent this (i.e. null refs from onCreate()).
Without checking for state is all my onCreate() functions is there a way to just prevent this?
Also, other than the launcher, recents, the back button from other apps - are there more conditions where another thing can launch my app if I have not giving manifest permission to launch it explicitly with an intent?
Thanks!
If I understand this correctly, you have initializations in activity B that rely on activity A having passed them in. If an intent launches activity B first, without it being active, or being launched by A first, your activity will crash.
Easiest solution I can come up with is make your activity A (I assume your main activity) the broadcast listener for all the intents you wish to handle, and based off the intent action, dispatch to the appropriate child activities (B, C, whatever). That way activity A does all your initialization, and you can still launch into the appropriate activity to handle the original intent you wanted to.
Alternatively. If you detect your children activities are in an invalid state, you could put initialization into a parent activity that all your activities extend from. That way you should be able to initialize properly if the activity is a fresh launch. I'm not really a fan of this, I prefer making sure my activities are dependency injected with appropriate data.
I have 2 activities. Main Activity A & Activity B
I do not want Activity A to destroy. I am starting Activity B in a new task.
public static void startActivity(Class<?> startClass) {
Intent intent = new Intent(Constants.getActivity(), startClass);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Constants.getActivity().startActivity(intent);
}`
Constants.getActivity() returns the Context on current activity
startClass is the either activity "A" or activity "B"
Thing is they create/destroy the activities and they leak. Am I doing it wrong? How can I start activity "B" from activity "A" and vice versa keep them both in background when I dont need them.
First of all, what are you trying to do? You should always separate things you want to do in the background from your UI. Think of your Activities are simply a container to show the UI, everything else can be stored and restored from persistent storage or savedinstance bundles.
It is very crucial that you understand the difference between Activity lifecycle and Service lifecycle here.
I'm going to refer to my answer from another question here:
Your app will be in the background, onResume and onPause will both be called, provided that the OS have enough memory to keep the new app and all the old apps.
If you have a long running process that you need while the user not looking at it, use a service.
If you need the user to return the app in the same state, you need to do the work in onResume and onPause to save the state information and initialize your UI again when the user comes back. If you are really worried that it can get killed (well, it shouldn't lose the bundle I think), you can store them in SharePreferences for your app.
If you want to know when the app returns from that specific share intent, use startActivityForResult
You cannot keep an activity "alive" as you said. When an activity is paused, Android system is always able to claim its memory and unload it, at any time.
But if you want to switch from A to B, then maybe A and B can be different views inside a single activity. Maybe you'll want to have a look at http://developer.android.com/reference/android/widget/ViewFlipper.html
When you use tasks, cleanup is very important. You need to cleanup all tasks in the activity. readthis
If the activity does not have a lot of crazy initialization, just use finish and onCreates. Else be aware that onResume will be called often as you switch between activity's. Cleanup will be crucial here. If you dont cleanup, its possible one of your activities (with dead object reference from the other cleaned up activity) may come back up from the activity stack and throw exceptions. Its very difficult to debug this kinda exception.
I have an application that navigates to the same activity but each time the activity loads with different parameters. In my application it's a parsed data content retrieved from url. First thing I want to ask: When I push the backbutton of my device I get my earlier activity without being recreated. Is the objects in this activities alive and can I reference them?
Second question is if my first question doesn't make sense, what do you advice me to do?
If you look at the Activity life cycle, you'll notice that as long as your phone has enough memory, your first activity is kept in memory, and with it any member with the data it contains.
But if your phone needs to have some memory, it can kill any activity kept in background (any activity but the one being shown to the user), which means that you'll loose any data that was in your first activity.
To know which happened, keep in mind that the onResume() method will always be called when your activity is brought to foreground (either on creation, or when you navigate back to it), but onCreate() will be called only when your application is created from scratch (meaning you don't have any saved data).
You should use the bundle mechanism to save data when your activity is paused, and load it when you come back to it. Read the paragraph about Saving Activity state in Android doc to see how to use this.
You are not guaranteed that in memory data will be around once you leave an Activity. Read through this part of the dev guide thoroughly to understand the lifecycle of an Activity: http://developer.android.com/guide/topics/fundamentals/activities.html
If you need to persist information, you should override the onPause, onStop, and/or onDestroy methods of your Activity. You can then save your state using SharedPreferences, the SQLite database, or even a flat file.
In the manifest file add the following to the activity:
android:launchMode="singleTop"
In your example what is happening is when you navigate back to the activity using the back button you are bringing up the activity from the stack. When you navigate to the activity inside of the app what is happening is a NEW activity is being created, while the original is still on the stack. The singleTop launch mode will pop the activity out of the stack if it is there when you navigate to it in the app, and only create a new activity if it is not on the stack.
Without singleTop each time you launch the activity in the app it will create a new instance and you will find there are times you have to hit the back button on the same activity more than once due to multiple instances.
My application has a main Activity A and that does a StartActivity on Activity B. If somebody uses a Task Killer (e.g., Advanced Task Killer), the application is killed but when they run the app again I see the Application object is being built (onCreate called) and then it goes right into Activity B not Activity A. The Manifest has A being the Launcher Activity.
I also see the scenario if I run A, then Activity B, bring down notification list and run Task Killer to kill my app, and press the Back key, it creates the Application object and then Activity B object.
Any ideas on how to prevent this behavior? Activity B assumes that Activity A has already run. I am able to kludge this but have a boolean in the Application object which is set on Activity A. In Activity B onCreate, if that global flag is not set, I do a finish(). Must be a better way to handle this since I have quite a few activities that would experience the same behavior.
Activity B should almost never assume any other Activity has run. Activities are meant to be stand alone units. If B must depend on A then there should be some test for a precondition and if it fails, opens ActivityA via an Intent.
Instead of keeping the flag in Application you may persist it in SharedPreferences - then your Activity B will always know the correct value of the flag.
I'm writing a simple Android app, and I'd like better control over the navigation/relationship between the activities. I don't want my activities to act like android activities...I don't want them to stack up within the Task. I want one Activity (let's call it MainActivity) to be the landing point and always be at the bottom of the stack, and I want only one instance of my second activity (call it SecondActivity) to be above it in the stack...would be nice to reuse it as well. I thought I could get this behavior by making MainActivity be the "main" Activity, and declare them both as launchMode=singleTop. This isn't working at all. I provide navigation between them using menus, so when I go back and forth a bunch of times and back out of the app, I go through the whole stack.
How's the best way to have fine control over the Task's Activity stack? I want MainActivity to always back out of the app, and SecondActivity to always back into a single instance of MainActivity. As well, I'd love to get singleTop working so I would use onNewIntent instead of creating and destroying every time. Using the manifest as well as the intent flag is just not working. Any ideas?
Well, you could always just call "finish()" within whatever Activity is calling another activity after the "startActivity()" call. I would definitely advise against trying to stuff an entire app into two activity classes and try to swap views based on what they're doing. If it's that important to you, just close your activities as you launch new ones (obviously not the MainActivity, though).