1. 程式人生 > >Android應用的預設Activity配置

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的類名作為名字來顯示。

這裡寫圖片描述

這裡順便說兩點:

  1. 如果一個APP將自身預設Activity的圖示和名字設定成和另一個APP的圖示和名字完全相同,但使用不同的包名,則應用安裝後用戶單從桌面上是很難區分的。

    這裡寫圖片描述

  2. 預設Activity的名字不宜太長,一般不宜超過10個英文字元(一個漢字算兩個英文字元),太長的名字會在桌面上顯示不全。

    這裡寫圖片描述

多個預設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的。

例如有如下配置:

<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">
    </activity>
</application>

MainActivity中沒有配置action android.intent.action.MAIN和android.intent.category.LAUNCHER,顯然它不是預設Activity。所以整個應用沒有一個預設Activity。

此外,作為沒有預設Activity特例,一個APP中也是可以沒有任何Activity的。

例如:

<application
    android:allowBackup="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來啟動。正常來說是不應該這樣配置的。