Android应用的默认Activity配置

Android应用的默认Activity

对一个Android应用来说,一般都会将某个Activity配置为默认启动的Activity。默认Activity作为应用的入口,会在桌面中显示一个图标和名字。这里稍作说明一下,Android原生系统采用二级桌面设置,应用安装后会显示在应用抽屉中,不会直接显示在外层桌面上,除非应用又在外层桌面创建了快捷方式。而大部分国内ROM都是采用一级桌面,取消了应用抽屉,应用安装后就直接显示在最外层的桌面上,这里忽略这个差异,之后都统称为桌面。当用户从桌面上点击应用图标,就会启动这个默认的Activity。

设置默认Activity的方式是在AndroidManifest.xml中为Activity添加intent-filter,并将action设置为android.intent.action.MAIN,category设置为android.intent.category.LAUNCHE。

示例如下:

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

默认Activity在桌面上的图标和名字

当配置了默认Activity的应用安装之后就会在桌面上显示一个图标和名字。其中图标由android:icon属性配置,名字则由android:label属性配置。

一般来说,我们都会在AndroidManifest的Application节点下配置这两个属性。

示例如下:

<application
    android:allowBackup="true"
    android:icon="@mipmap/app_icon"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

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

这里应用安装后在桌面上显示的图标就是@mipmap/app_icon对应的图像,显示的名字是@string/app_name对应的字符串。

但实际上在Activity节点下也是可以配置这两项属性的。

示例如下:

<application
    android:allowBackup="true"
    android:icon="@mipmap/appicon"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity"
              android:icon="@drawable/activity_icon"
              android:label="@string/acitivity_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        intent-filter>
    activity>
application>

Android中桌面显示的图标和名字的规则是:如果默认Activity中配置了android:icon,则桌面图标会显示成该配置对应的图像,如果默认Activity中没有配置android:icon,则会使用Application下的android:icon配置。同样如果默认Activity中配置了android:label,则桌面图标会显示成该配置对应的名字,如果默认Activity中没有配置android:label,则会使用Application下的android:label配置。

因此,在上述例子中,应用安装后在桌面上显示的图标就是@drawable/activity_icon对应的图像,显示的名字是@string/acitivity_name对应的字符串。

特别的,如果默认Activity和Application下都没有配置android:icon,则桌面会显示一个系统的默认图标。这通常是一个Android机器人。如果默认Activity和Application下都没有配置android:label,则会将默认Activity的类名作为名字来显示。

Android应用的默认Activity配置_第1张图片

这里顺便说两点:

  1. 如果一个APP将自身默认Activity的图标和名字设置成和另一个APP的图标和名字完全相同,但使用不同的包名,则应用安装后用户单从桌面上是很难区分的。

    Android应用的默认Activity配置_第2张图片

  2. 默认Activity的名字不宜太长,一般不宜超过10个英文字符(一个汉字算两个英文字符),太长的名字会在桌面上显示不全。

    Android应用的默认Activity配置_第3张图片

多个默认Activity配置

一般来说一个应用只会将一个Activity配置为默认Activity,作为应用的入口。但实际上Android是支持配置多个默认Activity的。只需要在AndroidManifest.xml中在每个需要作为默认Activity的节点下增加上述intent-filter配置即可。

示例如下:

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

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

多个默认Activity配置下的桌面图标和名字

如果配置了多个默认Activity,则应用安装后会在桌面上会显示多个图标和名字,有多少个默认Activity就显示多少个图标和名字,每个默认Activity对应一个图标和名字。

各个默认Activity的图标和名字显示的规则和一个默认Activity配置是一样的。也就是一个默认Activity的图标会优先使用该Activity节点下的android:icon配置,如果没有,再使用Application下的android:icon配置,如果还没有,则使用系统默认图标。一个默认Activity的名字会优先使用该Activity节点下的android:label配置,如果没有,再使用Application下的android:label配置,如果还没有,则使用应用包名。

例如有如下配置:

<application
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity"
              android:icon="@drawable/activity_icon_1"
              android:label="@string/acitivity_name_1">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        intent-filter>
    activity>

    <activity android:name=".SecondActivity"
              android:icon="@drawable/activity_icon_2">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        intent-filter>
    activity>

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

该应用安装后会在桌面上显示3个图标和名字。MainActivity配置了android:icon和android:label,因此它对应的桌面图标是@drawable/activity_icon_1,名字是@string/acitivity_name_1,SecondActivity只配置了android:icon,没有配置android:label,它会使用Application中配置的android:label,因此SecondActivity对应的图标是@drawable/activity_icon_2,名字是@string/app_name。ThirdActivity中没有配置android:icon和android:label,而Application中只配置了android:label,并没有配置android:icon,因此ThirdActivity对应的图标是系统默认图标,名字是@string/app_name。

一般来说,如果应用确实需要配置多个默认Activity,应该为每个默认Activity配置不同的图标和名字。

多个默认Activity使用注意事项

使用多个默认Activity时有几点需要注意:

  1. 对多默认Activity的应用,它们之间并非是相互独立的,而是运行在同一个进程中,共享同一个Application。
    例如,有一个应用,它有两个默认Activity,分别为MainActivity和SecondActivity。假设应用此时还未启动,先点击MainActivity,则会创建一个新的进程,并初始化应用的Application,然后按下返回键,结束MainActivity,这时回到桌面点击SecondActivity对应的图标,SecondActivity会正常启动,但并不会创建新的进程,仍然和之前的MainActivity运行在同一个进程中,Application也不会重新初始化。

  2. 对多默认Activity的应用,点击桌面上某个Activity对应的图标,并不能确定该Activity一定会启动。
    同样以上述包含两个默认Activity的应用为例。假设应用此时还未启动,先点击MainActivity对应的图标,则会创建一个新的进程,并初始化应用的Application,然后启动MainActivity。接着按下Home切换到桌面,然后按下SecondActivity对应的图标,如果SecondActivity的启动模式是标准模式,这时会仍然显示MainActivity,SecondActivity并不会被启动。

  3. 对多默认Activity的应用,当应用被卸载后,桌面上该应用的所有默认Activity对应的图标和名字都会被移除。
    这也很好理解,毕竟卸载的是应用,而不是某个Activity。试图在桌面上只移除一个默认Activity的图标而保留其他的默认Activity,是无法做到的(对有应用抽屉的Android系统,桌面上的快捷方式是可以随意移除的,这里指的不是快捷方式)。

默认Activity配置补充说明

上面所有默认Activity配置中,在intent-filter节点下都包含了两条配置。action android:name=”android.intent.action.MAIN”和category android:name=”android.intent.category.LAUNCHER”。如果要将一个Activity作为APP的默认Activity显示在桌面上,这两条必须同时配置。如果只配置了其中一条,那么该Activity是不能作为默认Activity的,应用安装后也不会在桌面上显示该Activity对应的图标和名字。

例如,如下配置中,只有MainActivity才是默认Activity,SecondActivity和ThirdActivity都不是默认Activity,应用安装后只会显示一个图标和名字,也就是@drawable/activityicon_1和@string/acitivity_name_1。

<application
    android:allowBackup="true"
    android:icon="@mipmap/appicon"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity"
              android:icon="@drawable/activityicon_1"
              android:label="@string/acitivity_name_1">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        intent-filter>
    activity>

    <activity android:name=".SecondActivity"
              android:icon="@drawable/activityicon_2"
              android:label="@string/acitivity_name_2">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        intent-filter>
    activity>

    <activity android:name=".ThirdActivity"
              android:icon="@drawable/activityicon_3"
              android:label="@string/acitivity_name_3">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER"/>
        intent-filter>
    activity>
application>

如果熟悉Android intent配置的话,应该知道category必须和action一起使用才有意义,所以单独的category配置是没有任何意义的。而action android.intent.action.MAIN的含义表示此Activity是应用的入口,在该action下有多个不同的category配置。android.intent.category.LAUNCHER表示该Activity要通过Launcher(也就是上面所说的桌面)来启动,除此之外,还有一些其他的category,具体可以查看Intent类中的category定义和对应的注释。

没有默认Activity配置

通常一个应用会至少有一个默认Activity的配置,然而这并非是强制要求。一个APP是可以没有默认Activity的。

例如有如下配置:

"true"
    android:icon="@mipmap/appicon"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    ".MainActivity"
              android:icon="@drawable/activityicon_1"
              android:label="@string/acitivity_name_1">
    </activity>
>

MainActivity中没有配置action android.intent.action.MAIN和android.intent.category.LAUNCHER,显然它不是默认Activity。所以整个应用没有一个默认Activity。

此外,作为没有默认Activity特例,一个APP中也是可以没有任何Activity的。

例如:

"true"
    android:icon="@mipmap/appicon"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

</application>

这个APP中没有任何Activity,也没有任何Service,Receiver,Provider。这样的APP同样是合法的,可以正确安装。

没有默认Activity的APP安装后,不会在系统桌面上显示任何图标和名字,也就是说从桌面上是找不到这个APP的踪影的。当然,在”系统设置” - “应用列表”中还是能够找到它们。在应用列表中可以显示所有已经安装的的应用,包括这类不会显示在桌面上没有默认Activity的应用。你也许会认为这类没有默认Activity的应用是没有意义的,但仔细查看手机应用列表,通常都会发现这里的应用数量要比桌面上的应用多很多,事实上有很多应用都是没有默认Activity的,例如,各类系统服务,Google Play 服务,Google框架,Google拼音输入法等。

没有默认Activity的应用的作用

如前所述,没有默认Activity的应用不会在桌面上显示图标和名字,但这并不代表它们没有作用。没有默认Activity的应用只是不能通过系统桌面这个入口来启动,它们仍然可以通过其他方式来使用。例如,AndroidManifest中定义的receiver,在收到特定广播后会由系统自动调用。再比如某个设置了exported=true的Activity,可以在其他APP中通过中来启动。

例如,通过如下代码就可以启动cnx.ccpat.test这个包中类名为cnx.ccpat.test.actvitity.nodefaultactivity的Activity。只需要nodefaultactivity其exported属性为true即可,并不需要是默认activity。

ComponentName componetName = new ComponentName("cnx.ccpat.test", "cnx.ccpat.test.actvitity.nodefaultactivity");
Intent intent= new Intent();
intent.setComponent(componetName);
startActivity(intent);

exported为false的默认Activity

对默认Activity,由于其配置了intent-filter,所以它的exported属性如果不做显式指定,则默认为true。但是可以在AndroidManifest中显式的将默认Activity的exported属性配置为false。

示例如下:

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

此时,APP可以正常安装,也可以正常显示图标和名字,但是点击图标会提示“未安装该应用程序”,也就是无法通过Launcher来启动。正常来说是不应该这样配置的。

你可能感兴趣的:(Android,Activity)