Как использовать различную активность запуска в аромате продукта?

Я работаю над проектом библиотеки Android, по умолчанию src/main/AndroidManifest.xml, MainActivity - это активность запуска.

Ради чего-то еще, я создал ароматы продукта. Да, он отлично работает, если я хочу запускать/показывать различные виды активности внутри разных продуктов. Тем не менее, я хочу сохранить действие по умолчанию запуска из папки src/main/, а зарегистрировать другую активированную деятельность в качестве новой активности запуска. Так что для разных вкусов продукта у меня могли быть разные действия с пусковыми установками, и из них я все равно мог начать оригинальную деятельность "запуска" в src/main/.

Может ли кто-нибудь любезно рассказать мне, как добиться этого? Большое спасибо.

Примечания:

  • Добавление кода if (BuildConfig.FLAVOR.equals("flavorName")) к исходной активности запуска не требуется. Потому что я не хочу изменять производственный код от кого-то другого (это проект библиотеки).

  • Я пробовал manifestmerger и tools:replace, но похоже, что он не работает для intent-filter (я заметил, что политика слияния элементов для фильтра намерения всегда).

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

Если это может сработать, не могли бы вы любезно посоветовать мне, как заставить его работать? Спасибо.

Ответы

Ответ 1

Что я пробовал:

  • Включение Слияние манифеста, которое не работает;
  • Использование псевдонима активности, который также не работает.

Наконец, я узнал, что проблему можно решить, просто добавив одну строку:

<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.

Ответ 2

Я думаю, что <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 от 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 и debug.
  • Мы должны ввести полное имя для псевдонимов активности, поэтому слияние может слить их правильно.

С помощью решения мы также можем наследовать все атрибуты и дочерние элементы из main алиаса активности, чтобы не дублировать их в debug.

Ответ 3

Самое простое и чистое решение - сохранить только один манифест и написать два разных класса 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

<?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>