Как использовать различную активность запуска в аромате продукта?
Я работаю над проектом библиотеки 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>
Ответ 4
Рабочее простейшее решение заключается в использовании слияния манифеста и использовании
<intent-filter tools:node="removeAll">
как предлагается в следующем сообщении:
Объединение файлов манифеста Android, конфликтный фильтр