Android Task: Once And For All

转载自:https://android.jlelse.eu/https-medium-com-yashsoniweb-android-tasks-ffbd547ff5b8

A short story to begin with:

In a place named  Androidland, there lived a guy called  Droid. He was a chef by profession and made delicious  Apps for living. He was very happy doing what he did. He had to be so, as he was following his passion.
One fine day, Droid was sitting in his verandah- sipping his favorite tea and wondering “How good a chef am I? I do know how to make best  APP-dishes in the world, given I already have best ingredients ready for me, but do I really know how these ingredients behave on their own?  OR  How they complement each other?   If not, then may be I’ve to learn that first. Because without clear fundamentals I can never become  best Chef for APP-dishes  ever.”
From that very day, Droid went on to the pursuit of becoming the best Chef in the Androidland, and guess what — at the end he did become one!

So with that story, we will begin with our Topic of the Day : Android Tasks(and everything around it!)

What is a Task in Android?

Simply put: A task is collection of Activities, usually co-related — but not necessarily. What you see in your “Recent-Apps” screen, is in-turn a collection of such Tasks.

What is a Back Stack?

While user navigates from one Activity to other, a stack is maintained by Android to persist the order of activities. This stack helps in which Activity to show when user clicks back button. Hence the name, Back Stack.

In most cases, you won’t need to worry about explicitly handling Tasks and Back Stack. But if you aspire become best Chef in Androidland, then you must know how to handle this stuff. ?


Consider this scenario:

Say you have an App with 2 Activities: A and B. 
Your Activity stack looks like this right now: A →B (B on the top of stack)

You are currently on Activity B. Now let’s say you get the notification that in-turn lands you to Activity B in your App.
What should ideally happen? 
You should stay on the same screen that is already open, right?

Well, this ideal scenario won’t happen on it’s own, you will end up making a new Activity on top of your current Activity. Resulting your Activity stack to look like: A → B → B

To get the desired output, let’s start with learning some new terms.

a) Task Affinity:

In general, what is affinity?

Like all of you have affinity for Android App Development,
Activities also have affinity towards default package, that is the reason all the Activities in one App falls under one task, by default.

Where can one define Task Affinity?

You define affinity per activity in your AndroidManifest.xml.
Affinity of an Activity is defined by following attribute within <activity> tag:

<activity
android:taskAffinity=""
..
/>

This parameter accepts a String. By default, every activity has same affinity as your package attribute value of mainfest tag.

<manifest package="com.example"...>

Affinity of a Task is defined by the affinity of its root Activity.

b) Launch modes:

It is used to instructs Android system on how to launch a particular activity.
Two ways to define 
launchMode  for an Activity:
1. In Manifest file
2. Using Intent Flags
Defining launch modes in Manifest File:

“android:launchMode” is an attribute defined inside <activity .../> tag in AndroidManifest.xml

<activity android:launchMode = [“standard” | “singleTop” | “singleTask” | “singleInstance”] ../>

1. “standard”:

This is the default mode. In case you don’t define any launchMode, the new activity is launched in standard mode. 
Here, a new instance of the Activity will be created — everytime.

2. “singleTop”

This is just as same as “standard” mode, except for — Android will perform an extra check “whether this activity is already on the top of the Activity Stack.” 
If YES, then it won’t create a new instance of the Activity but instead it will call the onNewIntent() of the same Activity.

Have a look at the Activity Stack for “standard” & “singleTop” launch modes. Consider the Activity Intent order as: A → B → B → B

3. “singleTask”

Here, the referred Activity will be launched in the new Task. 
(PS: You can notice this in Recents window)

So, you just define “launchMode”: “singleTask” and it will all work magically, huh?

 

Look Who’s Talking ;)

Your current activity has to have a “taskAffinity” value defined other than the default package name. Or else, even though you have tagged it as “singleTask” it will still open it in the same damn Task. 
One last important point to note is:

You CAN still have other Activities coming on top of this Activity, even in the newly created Task.

4. “singleInstance”

Well, this is exactly same as “singleTask” with one teeny-tiny difference. 
That is:

You CANNOT have other Activities coming on top of this Activity. This Activity is a lone warrior in the Tasks playground. ?

General Note on using “singleTask” & “singleInstance”:

When you launch an activity with a  launchMode  defined in Manifest, the Android system looks for the  taskAffinity  first. Then in the main stack of Tasks (i.e. Recents screen), Android checks if there is a task already present with the root Activity having same taskAffinity as the one for intended Activity, if  Yes , then the Activity is opened in that task,  else  a new task is created and with  Intended Activity placed at its root .
Defining launch modes using Intent Flags:

1. “FLAG_ACTIVITY_NEW_TASK”:

Now, putting it straight — this is just as same behaviour as 
launchMode — singleTask. 
Here, you do the same thing programmatically while creating your Intent for new Activity. Your code will look something like this:

Intent i = new Intent(FirstActivity.this, SecondActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);

Notes:

a) If you haven’t defined taskAffinity value different from the default one, setting this flag will have no effect. (Just like you did when using launchMode — singleTask)

b) The default behaviour of back press on newly created activity in a new task is — GO TO HOMESCREEN. If you want to go back to the Activity in your main task, that started this new Activity, then you have to define it in Manifest of your app. See the following snippet:

<activity android:name=".SecondActivity"
    android:taskAffinity="com.yash.soni"
    android:parentActivityName=".FirstActivity"/>

2. “FLAG_ACTIVITY_SINGLE_TOP”:

Again, this is same as launchMode — singleTop. You have to set the Intent Flag as follows:

Intent i = new Intent(FirstActivity.this, FirstActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);

Now, if the Activity to be launched is on the Top of the Activity stack, then instead of creating a new Activity, it will call onNewIntent() of the already open Activity. A sample snippet is as follows:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Toast.makeText(this, "Welcome again!", Toast.LENGTH_SHORT).show();
}

3. “FLAG_ACTIVITY_CLEAR_TOP”:

There are two scenarios of use here:
a) All Activities in the same Task:
As expected, this flag will clear all the Activities on the top of Intended Activity in the stack and bring it to Foreground.

b) Activities spread across different tasks:
If this flag is set along with FLAG_ACTIVITY_NEW_TASK then the system will bring the required Task that contains the intended Activity to Foreground, and clear all the Activities on the top of that Activity.


That will be a wrap on Android Tasks from my side.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值