Android implicitly starts Activity: action, category, data

Android start Activity divided into two types: display start and implicitly start

Display startup : It is to specify the package name + class name Activity through the Intent, which is the most commonly used startup method in development, not to mention it here, it is not the goal of this article

Implicit startup : now talk about implicit startup. The implicit start is also through the Intent, but the matching data must be added to the Intent, and the matching data must be matched with one of the filters of the target Activity before the target Activity can be started. For matching data and filters, please see below:

 

An activity that can be started implicitly must be configured with one or more filters <intent-filter> in the manifest file AndroidManifest.xml ,

Hereinafter, intent-filter is collectively referred to as: filter 

The role of this filter is: I can start outside this Activity, but I have to match one of the  filters, you can start the Activity.

Focus! ! ! ! ------ Match one of the filters to start the target Activity

 

First demo, the filter is configured for Activity in  AndroidManifest.xml . such as:

        <activity android:name=".filter.FilterActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>

            <intent-filter>
                <action android:name="FilterActivity_Action1"/>
                <action android:name="FilterActivity_Action2"/>
                <category android:name="FilterActivity_Category1"/>
                <category android:name="FilterActivity_Category2"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="test"
                      android:host="11"
                      android:port="8080">
                </data>
                <data android:scheme="test2"
                      android:host="22"
                      android:port="8081"
                      android:pathPattern="string"
                      android:path="/string"
                      android:mimeType="string">
                </data>
            </intent-filter>
        </activity>

 

 

Obviously, FilterActivity is configured with two filters  <intent-filter>. After talking for so long, how does one succeed in matching the previous filter?

Don't worry, let's take a look at the structure of the filter first. Looking at the configuration above, you can see that a filter has three parameters, namely:

1>  action

2>  category

3>  data

 

The type of 1 and 2 parameters is character type. 3 is Uri + mimeType

Also, each of these three parameters can have one or more. Such as the above

Action parameter : There are two parameters FilterActivity_Action1 and FilterActivity_Action2

category parameter: there are two parameters FilterActivity_Category1 and FilterActivity_Category2

data parameter:  There are 2 in the form of Uri + mimeType (what will be discussed later)

 

 

For the time being, let’s not talk about the subdivision matching of each parameter, just ask: How can it be considered as a complete match for the previous filter?

Answer: It means that an Intent must match the three conditions of this filter: action, category and  data. 

How can it be counted as a match, we split one by one

==========[ action matching rules ]=============

Action is a kind of string, in fact, the system also defines some strings, such as: android.intent.action.MAIN

But we can define ourselves such as the above: FilterActivity_Action1 and  FilterActivity_Action2 

The action matching rule is: as long as the Intent action matches one of the filter actions, the match is successful. Matching here refers to exactly the same string. Case sensitive. For example, in the above code, as long as the Intent's Action is set to: FilterActivity_Action1 or  FilterActivity_Action2  , the matching can be successful.

There is another point: Intent Action must have, and it cannot be matched successfully if it is not set. Because if it is not set, it cannot match any action of the filter.

 

==========[ category matching rules ]=============

Category  is actually similar to action   , and it is also a kind of string. In fact, the system also defines some strings, which can also be defined by yourself. The match is also an exact match of the string.

Such as the above  category  : FilterActivity_Category1 and  FilterActivity_Category2

The difference between category  and  action   is that category   can be omitted. You can match successfully without writing.

But as long as the category is configured for  the Intent, all categories of the Intent must match the filter successfully. Otherwise, the match fails.

In other words, the category set by the Intent must be in the filter, as long as the filter is not included, it will fail.

 

For example, take the above code:

My Intent sets   FilterActivity_Category1FilterActivity_Category2 and  FilterActivity_Category3

But the filter only has  FilterActivity_Category1 and  FilterActivity_Category2

Then the match fails.

 

Another point is that when the system calls startActivity, it will add android.intent.category.DEFAULT to our Intent by default 

This category. So if your Activity wants to be started implicitly, it must be configured in each filter:

<category android:name="android.intent.category.DEFAULT"/>   Otherwise, it will not start.

why? In fact, the above has been very clear. . . . .

 

==========[ data matching rule ]=============

The data   Intent must contain data, and each data in the Intent must match the filter.

But, what are the matching rules for data? This is different from the previous two, it is not a simple string match.

Before talking about the matching rules of data, let me add the form of data:

Data consists of two parts: Uri and mimeType, namely:

data = Uri  +  mimeType

 

 

[MimeType] refers to the media type, image/png , audio/mpeg4-generic and video/*, etc., respectively refer to pictures, texts, videos, etc.

【Uri 】 :的形式是:<scheme> : //<host> : <port>/  <path> |  <pathPrefix> | <pathPattern>

For example: https://www.baidu.com:8080/sraech/football  or content://com.demo.test:200//folder/subfolder/etd   

 

The scheme is in the form of Uri, which can be: file, coontent, http, etc.

Host is the domain name, such as: www.baidu.com

port is the port, for example: 8080

path, pathPrefix and pathPattern represent path parameters

 

That said, Chase parsing, how can it be considered a match?

[ Rule 1-Uri is not specified ]

Such as:

<data android:mimeType="image/*">
</data>

If Uri is not specified, the system will set Uri for this data by default, which is: content or File

The current mimeType is Image type. Intent data, such as file or conten, type is Image

such as:

Intent intent = new Intent();
intent.setDataAndType(Uri.parse("file://abcd"),"image/png");

In this way, the data in the Intent can match the data in the filter.

Here is a reminder that when setting data and type, call the  setDataAndType() method.

Do not call setData() first and then  setType() , these two methods will clear each other at the same time. Just look at the source code.

 

[ Rule 2-Uri is specified ]

such as:

<data android:scheme="http" android:host="www.test.com" android:mimeType="video/mpeg"></data>
<data android:scheme="http" android:host="www.test.com" android:mimeType="audio/mpeg"></data>

Then, the Intent must be configured in this way to match the data

intent.setDataAndType(Uri.parse("http://www.test.com"),"video/mpeg");

or

intent.setDataAndType(Uri.parse("http://www.test.com"),"audio/mpeg");

 

 

Two examples are given, which is basically clear.

The matching rule for data is: Uri and mimeType must be matched at the same time

 

Well, we give a few complete filters, such as:

            <intent-filter>
                <action android:name="action1"/>
                <action android:name="action2"/>
                <category android:name="category1"/>
                <category android:name="category2"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="test1" android:host="11" android:port="8080"></data>
                <data android:scheme="http" android:host="www.test.com" android:mimeType="video/mpeg"></data>
                <data android:scheme="http" android:host="www.test.com" android:mimeType="audio/mpeg"></data>
            </intent-filter>

 

Then we start this Activty implicitly:

/**
     *      隐式启动Activity
     * */
    public void test(Activity activity) {
        Intent intent = new Intent();
        //Action只需匹配上一个即可
        intent.setAction("action1");
        //Category必须全部匹配上
        intent.addCategory("category1");
        intent.addCategory("category2");
        //android.intent.category.DEFAULT 这个加不加都没问题,
        // 因为系统会默认给Intent加上,但是AndroidManifest.xml里就必须加上
        intent.addCategory("android.intent.category.DEFAULT");
        //Action只需匹配上一个即可
        intent.setDataAndType(Uri.parse("http://www.test.com"), "video/mpeg");
        activity.startActivity(intent);
    }

 

The above code pro test can start the target Activity.

 

Finally, to summarize.

action

Intent must be set with action, and the filter must have exactly the same action as one of the actions, otherwise the match will fail. Intent can only set one action at most, because every setAction will overwrite the previous action. See the source code to know...

 

category

Intent must be set category, you can set multiple, as long as the category set in the Intent, there must be in the filter. Otherwise, the match fails.

Reminder: The system will add android.intent.category.DEFAULT to the Intent by default, so the activity that can be started implicitly must add this category to the filter.

 

data

Intent must be set with data, and the filter must have matching data. The so-called matching is: Uri and mimeType must be exactly the same. Otherwise, the match fails. Intent can only set one data at most, because each time setDataAndType will overwrite the previous one. See the source code to know...

 

 

[ Intent-filter filter ]

An Activity can have multiple filters. Each filter must have one or more action, category and data at the same time.

As long as the Intent matches one of the filters, the Activity can be started.

Matching this filter means matching the action, category and data of this filter at the same time.

 

The intent-filter  mentioned above  is actually also applicable to BroadcastReceiver and Service.

However, the system recommends that the Service be started with the display as much as possible.

 

The above code test is no problem, please leave a message if you have any questions. Thank you!

 

 

 

 

Guess you like

Origin blog.csdn.net/Leo_Liang_jie/article/details/92836838