如何让安卓应用有两个入口

在使用鼎鼎大名的 leakcanary 检测内存泄漏时,我们发现,添加了 leakcanary 依赖后,再次运行 app 时,桌面上会多一个应用图标。

leakcanary

打开这个 Leaks 应用就能看到自己的 app 中存在的内存泄漏。

让桌面上多一个应用图标,这是怎么做到的呢?

答案是使用 activity-alias

一、为应用设置两个入口,分别启动两个 Activity

举个例子,通过 activity-alias 为应用程序指定另一个入口:

<activity
    android:name=".MainActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name=".SecondActivity"
    android:exported="false"
    android:taskAffinity="second.affinity"/>
<activity-alias
    android:name="SecondActivity"
    android:exported="true"
    android:icon="@mipmap/ic_launcher"
    android:label="SecondActivity"
    android:targetActivity=".SecondActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>
复制代码

可以看到,应用入口是 MainActivity,但我们通过 activity-alias 给 SecondActivity 也设置了应用入口的 intent-filter,安装后,桌面就会有两个入口:

activity-alias

点击两个图标就会启动两个不同的 Activity。这里还给 SecondActivity 设置了 taskAffinity,目的是让 SecondActivity 启动时,被放在一个新的栈中。

二、为应用设置两个入口,启动同一个 Activity

activity-alias 添加入口时,是不是一定要启动不同的 Activity 呢?

答案是不一定。activity-alias 也允许我们为同一个 Activity 定义多个别名,从而实现一个应用程序拥有多个图标或多个启动入口的效果。

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity-alias
    android:name=".Alias"
    android:icon="@mipmap/ic_chrome"
    android:label="Fake Chrome"
    android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>
复制代码

可以看到,应用入口是 MainActivity,但我们通过 activity-alias 给 MainActivity 又设置了一个别名,安装后,桌面就会有两个入口:

activity-alias

点击两个图标都会启动同一个 Activity。

三、activity-alias 还能做什么?

如果我们需要设置一个 Activity 支持打开网页,通常会采用这样的做法:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" />
    </intent-filter>
</activity>
复制代码

这里给 MainActivity 添加了支持打开网页的 intent-filter。运行后,当遇到打开链接的请求时,就会弹出这样的对话框:

open with

除了这种方式,activity-alias 也可以实现同样的功能。

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity-alias
    android:name=".browser"
    android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" />
    </intent-filter>
</activity-alias>
复制代码

另外,activity-alias 还可以给我们的应用再加一个 label 说明。

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity-alias
    android:name=".browser"
    android:label="My Browser"
    android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" />
    </intent-filter>
</activity-alias>
复制代码

此时再打开链接,就会在 My Application 底部展示我们新增的 label: My Browser:

My Browser

四、总结

activity-alias 为应用程序提供了更多的灵活性和可定制性。使用activity-alias,我们可以为一个Activity定义多个入口,从而增强应用程序的用户体验。

五、参考文章

# 冷知识 —— 如何实现 LeakCanary 桌面多出一个“新应用”的效果

猜你喜欢

转载自juejin.im/post/7226911455878479931