如何在产品风味中使用不同的启动器活动?

时间:2015-08-31 21:57:22

标签: android android-intent android-manifest android-productflavors

我正在使用Android库项目,在默认的src / main / AndroidManifest.xml中,MainActivity是启动器活动。

为了别的原因,我创造了产品口味。是的,如果我想在不同的产品口味中触发/显示不同的活动炎,它是完美的。但是,我想保留 src / main / 文件夹中的默认启动器活动,同时将另一种风格的活动注册为新的启动器活动。因此,对于不同的产品口味,我可以有不同的发射器活动,从中我仍然可以开始原始的#34;发射器" src / main /.

中的活动

有人可以告诉我如何实现这一目标吗?非常感谢。

注意:

  1. 不首选将if (BuildConfig.FLAVOR.equals("flavorName"))代码添加到原始启动器活动中。因为我不想从别人那里修改生产代码(这是一个图书馆项目)。

  2. 我已尝试过manifestmergertools:replace,但似乎它不适用于intent-filter(我注意到该元素合并了意图的政策-filter总是)。

  3. <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />

    如果这可能有效,请您指导我如何使其发挥作用?感谢。

7 个答案:

答案 0 :(得分:29)

我尝试过:

  1. 启用清单合并,但不起作用;
  2. 使用活动别名,这也不起作用。
  3. 最后我发现只需添加一行即可解决问题:

    <category android:name="android.intent.category.DEFAULT" />
    

    =============================================== ===

    为了说清楚,我将再次解决问题和解决方案:

    src/main/java下有一个MainActivity,在相应的src/main/AndroidManifest.xml中,它将MainActivity指定为启动器活动:

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

    这是一个非常容易的部分。现在我们从产品风味部分开始。

    由于某种原因,在产品风格方面,我不想覆盖MainActivity,而是我有一个YetAnotherMainActivity。目标是YetAnotherMainActivity设置为产品风格中的新启动器活动,并且仍然可以调用MainActivity

    在这里,您可以将产品风味中的新活动设置为新的启动器活动:

    flavorX/AndroidManifest.xml

    <activity android:name="com.example.YetAnotherMainActivity"
        android:label="@string/title_yet_another_main_activity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    

    是的,事实证明这很致命。只需添加android.intent.category.DEFAULT

答案 1 :(得分:7)

我认为<activity-alias>比任何其他解决方案都更适合(不知道为什么@JingLi无法使它工作。也许一年前有一些麻烦,但现在没关系。)

例如,我们在main中有以下清单:

<manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.application">
    <application>
        <activity android:name=".InfoActivity"/>
        <activity-alias 
            android:name="com.example.application.Launcher"
            android:targetActivity=".InfoActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity-alias>
    </application>
</manifest>

我们希望将DebugInfoActivity的{​​{1}}替换启动器活动。因此,我们只需要替换指定的debug代码中的targetActivity属性:

<activity-alias>

注意:

  • 在示例中,我们对<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application> <activity android:name=".DebugInfoActivity"/> <!-- to not litter the manifest --> <activity android:name="com.example.application.InfoActivity" tools:node="remove"/> <activity-alias android:name="com.example.application.Launcher" android:targetActivity=".DebugInfoActivity" tools:replace="android:targetActivity"/> </application> </manifest> main使用相同的包名称。
  • 我们必须输入activity-alias的全名,这样合并才能正确合并。

使用该解决方案,我们还可以继承debug个活动别名中的所有属性和子项,而不是在main中复制它们。

答案 2 :(得分:0)

我想我不迟到:) 所以今天我遇到了同样的问题。 @seroperson解决方案是正确的,但是如果您根本不希望使用默认的启动器活动,则只需在风味清单中使用以下代码即可:

<activity
        android:name=".DefaultLauncherActivity"
        tools:node="remove"
        >

答案 3 :(得分:0)

Android 合并正在将 intent-filter 从主清单 lancher 合并到风味。我还没有找到防止这种情况的方法。您最终会在设备上看到 2 个应用图标(每个图标用于启动器活动)。

基于此,您无法完全覆盖主清单中的设置。解决办法可能是在主文件夹中只保留清单的外壳并在每个风味中实现清单,或者从主文件夹中删除冲突活动并在每个风味中独立实现。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.adamassistant.app">

    <!-- empty shell, implementation in flavors folders -->

</manifest>

答案 4 :(得分:-1)

创建一个不同的AndroidManifest.xml文件。并将您的DifferentFlavorMainActivity.java设置为启动器活动,其全名如下:

android:name="com.android.application.paid.MainActivity"

答案 5 :(得分:-2)

最简单,最干净的解决方案是只保留一个Manifest并为每个flavor编写两个不同的MainActivity.java类,以避免重复清单节点。

在gradle中给出两种口味

productFlavors {
        paid {
            packageName "com.example"
        }

        demo {
            packageName "com.example.demo"
        }
    }

鉴于此项目结构

app/
|--libs/
|--src/
   |--paid/
   |  |--java/
   |     |--com/example/
   |        |--MainActivity.java
   |--demo/
   |  |--java/
   |     |--com/example/
   |        |--MainActivity.java
   |--main/
      |--java/
      |  |--...
      |--res/
      |  |--...
      |--AndroidManifest.xml

这个Android Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.flavors">

    <application
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">

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

    </application>

</manifest>

答案 6 :(得分:-3)

最简单的解决方案是使用清单合并和使用

<intent-filter tools:node="removeAll">  

如以下帖子所示:

Merging android manifest files, conflicting filter