Understand Android Activity’s launchMode: standard, singleTop, singleTask and singleInstance

Activity is one of the most brilliant concept on Android from its well-design architecture on memory management which lets Multitasking works perfectly on this most popular mobile operating system.

Anyway, Activity is not just to be launched on the screen. The way it is launched is also concerned. There are so many details in this topic. One of those that is really important is launchMode, which is the one that we are going to talk about in this blog.

Since each Activity is made to work in different purpose. Some is designed to work separately with each Intent sent for example an Activity for email composing in email client. While some is designed to work as a singleton for example an email’s inbox Activity.

That’s why it does matter to specify whether Activity is needed to be created a new one or to use the existed one, or it may leads to the bad UX or malfunctional. Thanks to Android’s core engineer. It is the way easy to make it done with some help of launchMode which is designed for this especially.

Assign a launchMode

Basically we could assign a launchMode directly as an attribute of <activity> tag inside AndroidManifest.xml file list this:

<activity
            android:name=".SingleTaskActivity"
            android:label="singleTask launchMode"
            android:launchMode="singleTask">

There are 4 types of launchMode available. Let’s see it one by one.

standard

This is the default mode.

The behavior of Activity set to this mode is a new Activity will always be created to work separately with each Intent sent. Imagine, if there are 10 Intents sent to compose an email, there should be 10 Activities launch to serve each Intent separately. As a result, there could be an unlimited number of this kind of Activity launched in a device.

Behavior on Android pre-Lollipop

This kind of Activity would be created and placed on top of stack in the same task as one that sent an Intent.

standardtopstandard

An image below shows what will happen when we share an image to a standard Activity. It will be stacked in the same task as described although they are from the different application.

standardgallery2

And this is what you will see in the Task Manager. (A little bit weird may be)

gallerystandard

If we switch the application to the another one and then switch back to Gallery, we will still see that standard launchMode place on top of Gallery’s task. As a result, if we need to do anything with Gallery, we have to finish our job in that additional Activity first.

Behavior on Android Lollipop

If those Activities are from the same application, it will work just like on pre-Lollipop, stacked on top of the task.

standardstandardl

But in case that an Intent is sent from a different application. New task will be created and the newly created Activity will be placed as a root Activity like below.

standardgalleryl

And this is what you will see in Task Manager.

gallerystandardl1

This happens because Task Management system is modified in Lollipop to make it better and more make sense. In Lollipop, you can just switch back to Gallery since they are in the different Task. You can fire another Intent, a new Task will be created to serve an Intent as same as the previous one.

gallerystandardl2

An example of this kind of Activity is a Compose Email Activity or a Social Network’s Status Posting Activity. If you think about an Activity that can work separately to serve an separate Intent, think about standard one.

singleTop

The next mode is singleTop. It acts almost the same as standard one which means that singleTop Activity instance could be created as many as we want. Only difference is if there already is an Activity instance with the same type at the top of stack in the caller Task, there would not be any new Activity created, instead an Intent will be sent to an existed Activity instance through onNewIntent() method.

singletop

In singleTop mode, you have to handle an incoming Intent in both onCreate() and onNewIntent() to make it works for all the cases.

A sample use case of this mode is a Search function. Let’s think about creating a search box which will lead you to a SearchActivity to see the search result. For better UX, normally we always put a search box in the search result page as well to enable user to do another search without pressing back.

Now imagine, if we always launch a new SearchActivity to serve new search result, 10 new Activities for 10 searching. It would be extremely weird when you press back since you have to press back for 10 times to pass through those search result Activities to get back to your root Activity.

Instead, if there is SearchActivity on top of stack, we better send an Intent to an existed Activity instance and let it update the search result. Now there will be only one SearchActivity placed on top of stack and you can simply press just back button for a single time to get back to previous Activity. Makes a lot more sense now.

Anyway singleTop works with the same task as caller only. If you expect an Intent to be sent to an existed Activity placed on top of any other Task, I have to disappoint you by saying that it doesn’t work that way. In case Intent is sent from another application to an singleTop Activity, a new Activity would be launched in the same aspect as standard launchMode (pre-Lollipop: placed on top of the caller Task, Lollipop: a new Task would be created).

singleTask

This mode is quite different from standard and singleTop. An Activity with singleTask launchMode is allowed to have only one instance in the system (a.k.a. Singleton). If there is an existed Activity instance in the system, the whole Task hold the instance would be moved to top while Intent would be delivered through onNewIntent() method. Otherwise, new Activity would be created and placed in the proper Task.

Working in the same application

If there is no that singleTask Activity instance existed in the system yet, new one would be created and simply placed on top of stack in the same Task.

singleTask1

But if there is an existed one, all of Activities placed above that singleTask Activity would be automatically and cruelly destroyed in the proper way (lifecycle trigged) to make that an Activity we want to appear on top of stack. In the mean time, an Intent would be sent to the singleTask Activity through the lovely onNewIntent() method.

singleTaskD

Doesn’t make a good sense in term of user experience but it is designed this way …

You may notice one thing that it is mentioned in document that

The system creates a new task and instantiates the activity at the root of the new task.

But from the experiment, it doesn’t seem to work as described. A singleTask Activity still stack up on top of the Task’s Activity stack as we can see from what dumpsys activity command shows up.

Task id #239
  TaskRecord{428efe30 #239 A=com.thecheesefactory.lab.launchmode U=0 sz=2}
  Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
    Hist #1: ActivityRecord{429a88d0 u0 com.thecheesefactory.lab.launchmode/.SingleTaskActivity t239}
      Intent { cmp=com.thecheesefactory.lab.launchmode/.SingleTaskActivity }
      ProcessRecord{42243130 18965:com.thecheesefactory.lab.launchmode/u0a123}
    Hist #0: ActivityRecord{425fec98 u0 com.thecheesefactory.lab.launchmode/.StandardActivity t239}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
      ProcessRecord{42243130 18965:com.thecheesefactory.lab.launchmode/u0a123}

If you wish to to let a singleTask Activity acts like described in document: create a new Task and put an Activity as a root Activity. You need to assign taskAffinity attribute to the singleTask Activity like this.

<activity
            android:name=".SingleTaskActivity"
            android:label="singleTask launchMode"
            android:launchMode="singleTask"
            android:taskAffinity="">

This is a result when we try to launch SingleTaskActivity.

singleTaskTaskAffinity

screenshot17

It’s your job to consider whether to use taskAffinity or not by the behavior of the Activity.

Collaborate with another application

Once an Intent is sent from another application and there is no any Activity instance created in the system yet, new Task would be created with a newly created Activity placed as a root Activity.

singleTaskAnotherApp1

singletaskfromapp2

Unless there is a Task of the application that is an owner of the calling singleTask Activity existed, a newly created Activity would be placed on top of it instead.

singleTaskAnotherApp2

In case that there is an Activity instance existed in any Task, the whole Task would be moved to top and every single Activity placed above the singleTask Activity will be destroyed with lifecycle. If back button is pressed, user has to travel through the Activities in the stack before going back to the caller Task.

singleTaskAnotherApp3

A sample use case of this mode is any Entry Point Activity for example Email Client’s Inbox page or Social Network’s Timeline. Those Activities are not designed to have more than one instance so singleTask would do a job perfectly. Anyway you have to use this mode wisely since Activities could be destroyed without user’s acknowledgement in this mode like described above.

singleInstance

This mode is quite close to singleTask, only single instance of Activity could be existed in the system. The difference is Task hold this Activity could have only one Activity, the singleInstance one. If another Activity is called from this kind of Activity, a new Task would be automatically created to place that new Activity. Likewise, if singleInstance Activity is called, new Task would be created to place the Activity.

Anyway the result is quite weird. From the information provided by dumpsys, it appears that there are two Tasks in the system but there is only one appeared in Task Manager depends on which is latest one that is moved to top. As a result, although there is a Task that is still working in the background but we couldn’t switch it back to foreground. Doesn’t make any sense at all.

This is what that happened when singleInstance Activity is called while there already is some Activity existed in the stack.

singleInstance

But this is what we see from Task Manager.

singleInstances

Since this Task could has only one Activity, we couldn’t switch back to Task #1 anymore. Only way to do so is to relaunch the application from launcher but it appears that the singleInstance Task would be hidden in the background instead.

Anyway there is some workaround for the issue. Just like we did with singleTask Acvity, simply assign a taskAffinity attribute to the singleInstance Activity to enable multiple Tasks on Task Manager.

<activity
            android:name=".SingleInstanceActivity"
            android:label="singleInstance launchMode"
            android:launchMode="singleInstance"
            android:taskAffinity="">

It makes more sense now.

screenshot18

This mode is rarely used. Some of the real use case is an Activity for Launcher or the application that you are 100% sure there is only one Activity. Anyway I suggest you not to use this mode unless it is really necessary.

Intent Flags

Beside from assigning the launch mode directly in AndroidManifest.xml, we are also able to assign more behavior through thing called Intent Flags, for example:

Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

would launch a StandardActivity with singleTop launchMode condition.

There are quite a lot of Flags you can play with. You could find more about it at Intent.

Hope you find this article useful =)

Ref: http://inthecheesefactory.com/blog/understand-android-activity-launchmode/en

Android OS Versions

Android OS Versions

 

Android is the most popular mobile operating system developed by Google based on the Linux kernel and designed primarily for touch-screen mobile devices such as smartphones and tablet .The first commercial version   Android 1.0  was released in September 2008. Android has a great journey of 5 year and in this journey we see many updates in Android versions.

Continue reading “Android OS Versions”

AsyncTask: Always not the Best Choice

Anyone that has done any sort of Android Development knows about the AsyncTask. Many developers live and breath by it. However, it can’t solve every problem that requires asynchronous messaging.

An AsyncTask provides a few handy functions that allow it to update the UI whenever it’s done doing work. OnProgreesUpdateOnPreExecute, and OnPostExecute allow the AsyncTask to update the UI with whatever information it needs. These methods work great when developing an Android client, but what about a Library?
Continue reading “AsyncTask: Always not the Best Choice”

Tips for More Efficient Application Development

The best recipe for becoming a complete flop in Google Play is to release an app that is battery and memory hungry with a slow interface. Most likely, these qualities will ensure negative reviews from users and result in a bad reputation, even if your app has great design and a unique idea.

Every drawback in product efficiency, battery and memory consumption can really affect your app’s success. That’s why it is critical to develop well-optimized, smooth running apps that never make Android system guard against them. We will not speak about efficient coding, since it goes without saying that the code you write should stand any performance test. But even brilliant code takes time to run. In today’s post, we’ll talk about how to minimize this time and make Android apps that users love.

Efficient threading

Tip 1. How to off-load operations onto threads in background

Since by default all operations in an app run on the main thread (UI thread) in the foreground, the app responsiveness might be affected, which will imminently result in hangs, freezes and even system errors.

To reinforce responsiveness, you should shift long-running tasks (e.g. network or database operations, complex calculations) from an app’s main thread to a separate background thread. The most effective way to accomplish this task is at a class level. You can use AsyncTask class or IntentService class to organize background work. Once you have implemented an IntentService, it starts when needed and handles requests (Intents) using a worker thread.

When using IntentService, you should consider the following limitations:

  • This class does not put results to UI, so to show results to users use Activity.
  • Only one request is processed at a time.
  • Any request processing can not be interrupted.

Tip 2. How to avoid ANR and stay responsive

The same approach of off-loading long-running operations from the UI thread will save your users from the “Application Not Responding” (ANR) dialog. What you need to do is to create a background worker thread by extending AsyncTask and implementing doInBackground() method.

Another option is to create a Thread or HandlerThread class of your own. Keep in mind that unless you specify “background” priority for the thread, it will slow down the app since the default thread priority is the same as of the UI thread.

Tip 3. How to initiate queries on separate threads

Displaying data is not immediate, although you can fasten it by using CursorLoader objects, which allows not to distract Activity from interacting with a user while query is processing in the background.

Armed with this object your app would initiate a separate background thread for each ContentProvider query and return results to Activity from which the query was called only when the query is finished.

Tip 4. What else you can do

  • Use StrictMode to detect potentially lengthy operations you do in the UI thread.
  • Use special tools, i.g. Systrace, Traceview, to find bottlenecks in your app responsiveness.
  • Show progress to users with a progress bar.
  • Display splash screens if initial setup is time-consuming.

Device battery life optimization

We cannot blame users for angrily uninstalling applications that abuse battery life. The main threats to battery life are:

  • Regular wake-ups for updates
  • Data transfer via EDGE and 3G
  • Textual data parsing, regex without JIT

Tip 5. How to optimize networking issues

  1. Make your app skip operations if there is no connection; update only if 3G or WiFi is connected and there is no roaming.
  2. Choose compact data format, e.g. binary formats that combine text and binary data into one request.
  3. Use efficient parser; consider choosing stream parsers over tree parsers.
  4. For faster UX lessen round-trip times to server.
  5. When possible use framework GZIP libs for text data to make the best use of CPU resources.

Tip 6. How to optimize apps working in foreground

  1. When designing wakelocks, set the lowest level possible.
  2. To avoid battery costs caused by potential bugs you might have missed, use specific timeouts.
  3. Enable android:keepScreenOn.
  4. In addition to GC (garbage collection) consider recycling Java objects manually, e.g. XmlPullParserFactory and BitmapFactory; Matcher.reset(newString) for regex; StringBuilder.setLength(0).
  5. Mind synchronization issues, although it can be safe when driven by UI thread.
  6. Recycling strategies are used heavily in ListView.
  7. Use coarse network location not GPS when possible. Just compare 1mAh for GPS (25 sec. * 140mA) and 0.1mAh for network (2 seconds * 180mA).
  8. Make sure to unregister as GPS location updates can continue even after onPause(). When all applications unregister, users can enable GPS in Settings without blowing the battery budget.
  9. Since the calculation of a floating point requires lots of battery power, you might consider using microdegrees for bulk geo math and caching values when performing DPI tasks with DisplayMetrics.

Tip 7. How to optimize apps working in background

  1. Since each process requires 2MB and might be restarted when foreground apps need memory, make sure the services are short-lived.
  2. Keep memory usage low.
  3. Design app to update every 30 minutes but only if device is already awake.
  4. Services that pall or sleep are bad, that is why you should use AlarmManager or <receiver> manifest elements: stopSelf() when finished. When you start service using AlarmManager, apply the *_WAKEUP flags with caution. Let Android bin your application update together with the rest through setInexactRepeating(). When using <receiver>, enable/disable its components in manifest dynamically, especially when no-ops.

Tip 8. What else you can do

  • Check current states of battery and network before launching a full update; wait for better states for bulk transfers.
  • Provide users with battery usage options, e.g. update intervals and background behavior.

Implementing UI that leaves minimum memory footprints

Tip 9. How to identify layout performance problems

When creating UI sticking solely to basic features of layout managers, you risk to create memory abusing apps with annoying delays in the UI. The first step to implementation of a smooth, memory caring UI is to search your application for potential layout performance bottlenecks with Hierarchy Viewer tool included into Android SDK: <sdk>/tools/.

Another great tool for discovering performance issues is Lint. It scans application sources for possible bugs along with view hierarchy optimizations.

Tip 10. How to fix them

If layout performance results reveal certain drawbacks, you might consider to flatten the layout by converting it from LinearLayout class to RelativeLayout class, lowing level hierarchy.

To perfection and beyond

Even though each tip mentioned above might seem like a rather small improvement, you might see unexpectedly efficient results if these tips become an essential part of your daily coding. Let Google Play see more brilliant apps that work smoothly, quickly, and consume less battery power, bringing the Android world one more step closer to perfection.

How to create great launcher icons in five easy steps

Creating great launcher icons quick and easy!

Some stuff you need to know

All apps need a launcher icon.

Our apps may run on devices with different screen sizes and densities so we’ll need different size icons.

Android has created 5 buckets for the different screen densities:

Screen density Required Icon sizes folder
Medium 48 x 48 drawable-mdpi
High 72 x 72 drawable-hdpi
Extra High 96 x 96 drawable-xhdpi
Extra-Extra-High 144 x 144 drawable-xxhdpi
Extra-Extra-Extra High 192 x 192 drawable-xxxhdpi

 

There is also a low density bucket but there’s no need to worry about that as Android will scale down the high density icon for this.

Continue reading “How to create great launcher icons in five easy steps”

Master Notifications: Some stuff you should know.

Notification icon

Master the basics of Android notifications

Notifications inform the user about something. They appear in the Notification area at the top of the screen.

The Notification area

Notification area

Here are a couple of examples:

  • The battery is getting low
  • An email has arrived
  • Your file download is complete

Users can read them whenever the like. They just drag the notification drawer down to open it.

Continue reading “Master Notifications: Some stuff you should know.”

15 quirky Android XML layout parameters to know

15 quirky Android XML layout parameters to know

After working on Android widgets for the last two years I’ve learned a lot about limitations, inconsistencies, and ghostly parameters in Android XML layout files. Some parameters are simply “overly clever” so I’ll offer some standard settings you should use.

These come in handy so take a moment to review. Continue reading “15 quirky Android XML layout parameters to know”

Android Development Tools

Hello All,

Here are few important android development tools

1] XAppDbg: XAppDbg is an app development tool that can be used to change parameters in your code during runtime. This can save you a lot of time, since you don’t have to build and run your application for each small change. Go to the XAppDbg page to download and learn more about this open sourced tool.
Read More
Continue reading “Android Development Tools”

Android vs iOS guide for newbies

In tech years, the iOS vs. Android argument seems like it is half a century old and has stretched the limits of human tolerance for passive-aggressive retorts. Since 2008 the ongoing comparisons between these operating systems have been in the spotlight because of the growing Android market and the possible iOS expectation that everything be done through Apple and with Apple products.

Continue reading “Android vs iOS guide for newbies”

Dissect layouts using Android’s Hierarchy View

Wouldn’t it be great if when you came across a user interface (UI) that really works you could get a behind-the-scenes look at the blueprints that brought together all those layouts, widgets, and views in such an ideal manner? Well guess what? You can do so, and I highly recommend you get into the habit of it.

Continue reading “Dissect layouts using Android’s Hierarchy View”