如何使用新的清单合并(Android Studio 和 Gradle)?
过去,当 Eclipse&ADT 是为 Android 开发的官方工具时,您只需在project.properties"中使用manifestmerger.enabled=true">" 的应用程序项目,你让它自动合并所有库的清单(我已经发布了关于它的在这里).
In the past, when Eclipse&ADT were the official tools to develop for Android, you could simply use "manifestmerger.enabled=true" inside the "project.properties" of the app's project, and you got it merging all of the libraries' manifests automatically (and I've posted about it here).
这有时奏效.它有很多奇怪的问题,我总是宁愿避免使用它,而是手动将所需的内容放入主清单文件中.
This worked, sometimes. It had a lot of weird issues, and I always preferred to just avoid using it, and put what is needed into the main manifest file manually.
在 2014 年的某个时候,Google 宣布新的 Android-Studio(我认为是 0.1)与 Gradle 一起允许您准确选择如何执行库组件的合并.
Somewhere on 2014, Google announced that the new Android-Studio (0.1 I think), together with Gradle, will allow you to choose exactly how to perform merging of libraries' components.
但是,新的说明(链接here) 非常复杂,我真的(真的)试图了解如何使用它们,但也没有找到如何使用它们的示例.
However, the new instructions (link here) are very complex and I really (really) tried to understand how to use them, and also didn't find samples of how to use them.
不是我什么都不懂,只是我不确定我是否理解得很好.
It's not that I didn't understand anything, but I'm not sure if I understood well.
从好的方面来说,我发现合并是完全自动完成的,所以如果你在库的清单上有一个 BroadcastReceiver(当然,作为一个类),它将被添加到使用的应用程序的项目中
On the bright side, I've found out that merging is done completely automatically, so if you have a BroadcastReceiver on the library's manifest (and as a class, of course), it will be added to the app's project that uses it.
我不能简单地要求解释一切.我认为提出这些问题就足够了:
I can't simply ask everything to be explained. I think it will be enough to ask those questions:
如何选择要忽略的应用组件(权限、活动等),以免自动合并?
How can I choose which app components (permissions, activities,...) to be ignored from being auto-merged?
我如何指向覆盖应用程序组件(库的)属性(在应用程序的项目上)?比如活动的主题?
How can I point override app components (of the library) attributes (on the app's project) ? for example the theme of the activities?
有没有办法完全禁用清单文件的自动合并?
Is there a way to completely disable the auto-merger for the manifest files?
存储库内的依赖项清单会发生什么?他们也合并了吗?
What happens with manifests of dependencies that are inside repositories? Are they merged too?
是否有关于这个新(对我来说是新的)功能的教程/示例/视频?
Are there any tutorials/samples/videos regarding this new (well new for me) feature?
在使用自动合并时有什么我应该注意的事情吗?
Are there any things I should be aware of when using the auto-merger?
我希望这些问题具有足够的代表性、足够的信息,但对于知道的人来说回答起来并不难.
I hope those questions are representative enough, informative enough, yet not too hard to answer for people who know.
1.禁用元素
您始终可以在应用清单中明确禁用权限和功能,并覆盖任何库值.我发现您可以禁用库中的元素.
示例
考虑上面链接中的以下代码:
Consider the following code from the above link:
<activity-alias android:name="foo.bar.alias">
<meta-data
android:name="zoo"
tools:node="remove" />
</activity-alias>
通过在您的清单中包含此代码,您可以确保合并找到任何带有 android:name=foo.bar.alias"
的
元素> 属性并删除
元素,如果它具有 android:name="zoo"
属性.它只删除了动物园"元数据.不是活动别名.如果您在主清单中指定此项,它将对目前已合并的任何内容(库中的元素)有效.
By having this code inside your manifest you ensure that the merger finds any <activity-alias>
elements with android:name="foo.bar.alias"
attribute and removes a <meta-data>
element if it has the android:name="zoo"
attribute. It removes just the "zoo" meta data. Not the activity alias. If you specify this in your main manifest it will be effective on anything that has been merged so far (elements from libraries).
示例#2
既然你要求了一个活动的例子,这就是我想出的:
Since you requested an example with activities, this is what I've come up with:
<activity android:name="com.example.ui.MyActivity" tools:node="remove" />
这一行将使合并删除迄今为止已合并的具有 android:name="com.example.ui.MyActivity"
属性的所有活动.因此,如果您在主清单中指定此项,它将有效地删除任何可能已从库中合并的 com.example.ui.MyActivity
条目.
This line will make the merger remove any activities with android:name="com.example.ui.MyActivity"
attribute that have been merged so far. So if you specify this in your main manifest it will effectively remove any com.example.ui.MyActivity
entries that might have been merged from libraries.
值合并的顺序在此处.基本上,它是这样的:库,然后是主清单,然后是风味和构建类型清单(如果您使用它们).
The order in which the values are merged are described here. Basically, it goes like this: libraries, then main manifest, then flavors and build types manifests if you use those.
什么是构建类型?
默认为调试";和释放".您可以定义自己的和覆盖设置,例如 signing 或 proguard.出于您的目的,您可以说它相当于运行配置.
The default are "debug" and "release". You can define your own and override settings like signing or proguard. For your purposes you could say it's the equivalent of run configurations.
它是这样工作的:您将默认值和共享值放在 main
清单中.然后在 flavor 清单中覆盖您需要的值.谷歌gradle 口味"了解更多信息.
It works like this: you put your default and shared values inside the main
manifest. Then in flavor manifests you override the values you need. Google "gradle flavors" for more info.
以下示例取自 之前版本的清单合并文档.
使用工具:replace=x,y,z";将覆盖 x,y,z 属性导入的库的活动 XML 声明.
Override an attribute coming from a library
Using tools:replace="x, y, z" will override x,y,z attributes from the imported library’s activity XML declarations.
更高优先级声明
<activity
android:name="com.foo.bar.ActivityOne"
android:screenOrientation="portrait"
android:theme="@theme1"
tools:replace="theme"/>
具有较低优先级的声明:
with a lower priority declaration :
<activity
android:name="com.foo.bar.ActivityOne"
android:theme="@olddogtheme"
android:windowSoftInputMode="stateUnchanged"
android:exported="true">
将导致:
<activity
android:name="com.foo.bar.ActivityOne"
android:screenOrientation="portrait"
android:theme="@theme1"
android:windowSoftInputMode="stateUnchanged"
android:exported="true"/>
3.完全禁用清单合并
请参阅在 Android Gradle Build 中禁用清单合并.>
android.applicationVariants.all { variant ->
variant.processResources.manifestFile = file('src/main/AndroidManifest.xml')
variant.processManifest.enabled=false
}
你把它放在什么文件里?
在你的模块(不是根项目)build.gradle
的末尾.
At the end of your module's (not root project) build.gradle
.
是的(它们是图书馆).
Yes they are (they're libraries).
有没有办法阻止合并某些库清单?
Is there a way to block merging certain library manifests?
我不知道,抱歉.
取决于你想达到什么目的.到目前为止,它对我来说总是开箱即用.
Depends on what are you trying to achive. So far it always worked for me out-of-the-box.
我不知道任何视频.
如果您对额外权限等感到怀疑,您可以检查生成的清单.它位于project/module/build/intermediates/manifests/full/[flavor]/build-type/AndroidManifest.xml
.
You can check the generated manifest if you get suspicious about extra permissions etc. It's located in project/module/build/intermediates/manifests/full/[flavor]/build-type/AndroidManifest.xml
.