- Android开发权威指南(第二版)
- 李宁编著
- 1461字
- 2024-12-21 14:45:53
7.3 Activity的别名
源代码目录:src/ch07/ActivityAlias
在AndroidManifest.xml文件中除了可以使用<activity>标签声明窗口外,还可以用更灵活的方式设置窗口的属性以及Action、Category等信息。这种灵活的方式就是本节要介绍的Activity别名。
Activity别名使用<activity-alias>标签声明。尽管将该技术称为Activity别名,但更像窗口设置的继承与覆盖。这是因为<activity-alias>标签必须使用targetActivity属性指定一个窗口名,也就是某一个<activity>标签的name属性值。除了targetActivity属性外,<activity-alias>标签的其他属性与<activity>标签的相应属性的含义完全一样。如果未设置<activity-alias>标签的某个属性,该属性值就会使用targetActivity属性值指定的<activity>标签中相应的属性值,也就是<activity-alias>标签的属性默认会继承与其对应的<activity>标签中相应的属性值。<activity-alias>标签支持的主要属性如下。
android:enabled。
android:exported。
android:icon。
android:label。
android:name。
android:permission。
Activity别名的用处比较广泛。例如,在5.1.1小节Activity的基本用法中介绍了如果在一个应用程序中(同一个<application>标签中)的多个窗口类声明中包含如下<intent-filter>标签,系统会在程序列表中生成多个图标,也就是只要安装该程序,就会一下出现多个程序图标,就像安装了多个程序一样。当单击某一个程序图标后就会显示与其对应的窗口。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
其实这种方法实际上可以通过不同的程序图标显示不同的窗口,那么如果要使用同一个窗口处理不同的业务逻辑呢?要实现这个需求,就要使用<activity-alias>标签为某个窗口定义一个别名。例如,在本例中有一个ActivityAliasMain类,该类是主窗口类,现在要使用ActivityAliasMain窗口处理两个不同的逻辑,也就是说一个主窗口要在程序列表中显示两个图标。实现这个需求需要使用到<activity-alias>标签,代码如下:
源代码文件:src/ch07/ActivityAlias/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mobile.android.activity.alias"
android:versionCode="1"
android:versionName="1.0" >
……
<application……>
<!-- 第1个主窗口 -->
<activity
android:name=".ActivityAliasMain"
android:label="@string/title_activity_activity_alias_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 第1个主窗口的别名 -->
<activity-alias
android:name=".AliasMain"
android:icon="@drawable/umbrella"
android:label="AliasMain"
android:targetActivity="ActivityAliasMain">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- 第2个主窗口 -->
<activity
android:name=".MyActivity"
android:icon="@drawable/calculator"
android:label="Calculator" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
……
</application>
</manifest>
在上面的代码中声明了两个主窗口,并为第一个主窗口定义了别名。该别名也使用了与主窗口同样的<intent-filter>标签。<activity-alias>标签的android:targetActivity指定了该标签定义了哪个窗口的别名。当运行程序后,会在程序列表中显示3个图标,如图7-26白框中所示,其中单击左上角的两个图标,都会显示ActivityAliasMain窗口,而单击另一个图标会显示MyActivity窗口。
▲图7-26 一个应用程序产生3 个图标
为了使用同一个窗口(ActivityAliasMain)处理两个逻辑(例如,装载不同的布局文件),可以通过窗口类名(也就是android:name属性值)来判断用户单击的是哪个程序图标。例如,可以在ActivityAliasMain.onCreate方法中获取窗类口名并进行判断。
源代码文件:src/ch07/ActvityAlias/src/mobile/android/activity/alias/ActivityAliasMain.java
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_alias_main);
// 比较窗口类名
if(".ActivityAliasMain".equals(getComponentName().getShortClassName()))
{
setTitle("使用了<activity>标签");
// 可以在这里完成相应的业务逻辑
}
else if(".AliasMain".equals(getComponentName().getShortClassName()))
{
setTitle("使用了<activity-alias>标签");
// 可以在这里完成相应的业务逻辑
}
}
Activity别名除了前面的应用外,还可以为任何一个窗口定义别名。例如,如果某一个窗口定义了若干个Action,而且要单独控制某一个Action是否可以被其他应用程序调用,这也要使用Activity别名。
在下面的代码中声明了一个TestActivity窗口,并为该窗口定义了一个窗口别名。该别名指定了一个action和category,并且可以通过android:exported属性决定是否可以通过其他程序调用TestActivity窗口。
源代码文件:src/ch07/ActivityAlias/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mobile.android.activity.alias"
android:versionCode="1"
android:versionName="1.0" >
……
<activity
android:name=".TestActivity"
android:label="TestActivity" />
<!-- 窗口的别名 -->
<activity-alias
android:name=".TestActivityAlias"
android:exported="true"
android:targetActivity=".TestActivity">
<intent-filter>
<action android:name="android.intent.action.TEST_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity-alias>
</application>
</manifest>
如果按照上面的设置,在任何程序中都可以使用下面的代码调用TestActivity窗口。
Intent intent = new Intent("android.intent.action.TEST_ACTION");
startActivity(intent);
使用<activity-alias>别名时应注意如下几点。
<activity-alias>标签的大多数属性都是可选的,但android:name和android:targetActivity属性必须设置。
android:name属性不能与android:targetActivity属性指定的<activity>标签的android:name属性值相同,否则尽管不会抛出异常,但该窗口别名将不再起作用。
android:targetActivity属性指定的<activity>标签必须在<activity-alias>标签之前声明,否则无法将程序安装到Android设备上。