I am finding it hard to understand the exact circumstances in which each the various launch modes would be used in Android. Could anyone provide me with some examples to help understand when the various modes are appropriate?
Between the Browser and Alarm Clock applications, you cover all four launch modes:
BrowserActivity uses singleTask. There is only one browser activity at a time and it doesn't become part tasks that send it intents to open web pages. While it might return to whatever most recently launched it when you hit back it is actually fixed at the bottom of its own task activity stack. It will share its task with activities that it launches like bookmarks.
BrowserBookmarksPage uses singleTop. While there can be multiple instances of this activity, if there is already one at the top of the task's activity stack it will be reused and onNewIntent() will be called. This way you only have to hit back once to return to the browser if the bookmarks activity is started multiple times.
AlarmClock uses standard. The user can launch multiple instances of this activity and these instances can be part of any task and anywhere in the activity stack. As a fairly simple application it doesn't really demand tight control of its activity.
AlarmAlert uses singleInstance. Only one alert activity at a time and it is always its own task. Anything it launches (if anything) becomes part of its own new task.
The official documentation is a bit confusing so here's a table to help.
http://androidisland.blogspot.com/2010/12/activity-launch-modes-simple.html
Related
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/
Thanks for reading by question, albeit a really noob-ish one...
How does the Android system manage memory with regards to activity initialization, specifically if an activity is initialized through other activities? This has been a lingering question in my mind for a while, but I'll try to illustrate with an example:
Say I have 3 activities - A, B and C - with activity A being the one that is launched when the application is started for the very first time. Now, let's say activity A has buttons to navigate to activities B and C, and those activities are launched using Android's startActivity() function, passing it an Intent instance. Similarly, let's say activities B and C have buttons to launch their counterpart activities...make sense so far?
Now, if I then use the startActivity() to:
start activity B from activity A
then start activity C from activity B
then start activity A from activity C
then repeat the above steps indefinitely (so going around in circles)
...would it be fair to assume that the Android system would "know" that the activities had already been started previously and wouldn't re-initialize them and kill more and more memory, but rather call something like the onRestart() functionality to rather "switch" back to an already initialized instance of the activity?
Quite an explanation for a really simple question / problem...apologies if this has already been asked and answered somewhere else...I couldn't find a clear answer anywhere else, even while reading through the Android training section on the Android developers site.
The answer is: It depends. :-)
If you use the standard settings for the activities A, B and C, your application will run out of memory. The reason is that Android will keep each activity in the "Back Stack" that allows the user to navigate back by pushing the back button.
However, if you set the android:launchMode of your activities to singleTop in the AndroidManifest.xml file then Android will route the intents to the running instances of the activities by invoking onNewIntent() in the activity.
You can read more about it in the Android Developer Documentation regarding launch modes.
I have a UI flow that has activities launched via intents in separate applications. For example, the first screen would be an activity in application B, launched from my application, the second from application C etc.
To control this flow I was thinking of using a service. Is this the correct approach? Or would it be better to use light weight activities with no UI to launch the external activities?
Not sure to understand correctly what you are trying to achieve, but
I think that startActivityForResult may be useful to you.
While application will be started, I want to launch one activity if some condition is satisfied else want to launch another activity. How to do this?
Start the one, and in onCreate() check the condition. If it is not satisfied start your another activity.
you must do it handling all conditions in an initial activity, which will check your rules and start the other activitys.
I don't know much about your particular use case, but if your application has to launch different activities depending on the task it is supposed to do, you should consider having appropriate intent-filters for each, and sending an Intent that's in accordance to the intended effect. That will make the correct activity be launched depending on the Intent, which is one of the great features of Android.
But of course, if you can only decide which activity is best once you launch your app, this approach doesn't work, and you have to launch an initial activity to decide which one to call next.
If it's highly likely that one activity will be launched, you might consider launching it as the first activity and then testing whether you need to launch another instead. That's probably cleaner than having a separate activity just to make the decision about which other activity to launch.
Bruno Oliveira, Developer Programs Engineer, Google
I have an android app. I added an intent filter to one of my activities, so that if a url is clicked in the browser app, my activity can be launched. Looks like this:
<data android:host="www.mysite.com" android:scheme="http"></data>
this works well. The problem is that every time my activity is launched from the browser, a new instance of the activity is created, inside the browser app's task, instead of recycling any existing instance that may be in the system already.
This is a problem for me because this activity uses a singleton. If I allow more than one instance of this activity to exist, I can get into some weird situations where the two instances are in conflict when they try to share the singleton. I checked and can see that although the activity instances may be in separate tasks, they do share the same singleton instance.
An ideal solution for me would be if I could somehow bring a pre-existing instance of my application to the foreground, and launch or resume the target activity within whatever pre-existing instance of my app happens to be running.
So I tried this:
Register above filter to point to dummy activity which is just a catcher.
Dummy activity creates a broadcast intent, and tries to broadcast 'create me' message to system.
Real target activity is set to listen for this broadcast message. Hopefully if there is already an instance of the activity in the system, it will come to the foreground. If no instance yet, that's ok, allow creation in the browser task.
Not sure if this makes sense. My basic goal is to limit the activity to one instance in the system. The app is just social media app which has a login state that needs to be preserved. The singleton mentioned above preserves that login state, so I want to have only one around in the system, instead of allowing multiple login instances running around which would be a headache for the user.
Thanks
You can set the activity launch mode to singleTop to achieve this.
android:launchMode
An instruction on how the activity should be launched. There are four modes that work in conjunction with activity flags (FLAG_ACTIVITY_* constants) in Intent objects to determine what should happen when the activity is called upon to handle an intent. They are:
"standard"
"singleTop"
"singleTask"
"singleInstance"
The default mode is "standard".
https://developer.android.com/guide/topics/manifest/activity-element.html#lmode