【问题标题】:Android build will not merge manifests from librariesAndroid 构建不会合并库中的清单
【发布时间】:2017-03-26 13:37:36
【问题描述】:

我们有多个项目,取决于许多 Android 库模块。 为避免应用清单中出现重复的 xml 标签,我们将相关的接收器、服务和活动放在各自的模块中。

直到今天,我们还在使用:

  • Android Studio:2.2.1
  • 分级:2.1.3
  • buildToolsVersion:23.0.3

今天我们更新为:

  • Android Studio:2.3
  • gradle: 2.3.0
  • buildToolsVersion: 25.0.0

在此更新之前,一切正常,并且清单已合并,我们遇到了冲突并修复了它们。在我们完成更新后,清单根本不会合并!!

--- 更新 1 ---

我们使用了 Merged Manifest 视图,发现它只是不包含合并中的清单,它从模块清单中合并的唯一事情是权限,例如,如果我添加一个新的对模块清单的权限只会合并它而不是其余元素!

我保证有很多东西要合并!

--- 更新 2 ---

似乎应用程序标记之外的所有内容都合并到主清单中,而应用程序标记中的所有内容都没有。

--- 更新 3 ---

不合并的模块:

分级:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion '25.0.0'

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            jniDebuggable true
        }
    }
}

dependencies {
    compile project(path: ':android-infra')
    compile 'com.google.android.gms:play-services-gcm:9.0.0'
    compile project(path: ':engine-core-server')
    compile project(path: ':engine-core-aneeda')
}

清单:

<manifest package="com.sensiya.voip.managers.gcm"
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="com.google.android.c2dm.permission.KAKI"/>


    <application
        tools:node="replace">
        <service
            android:enabled="true"
          android:name="com.sensiya.voip.managers.gcm.GcmIntentService"/>

        <receiver          android:name="com.sensiya.voip.managers.gcm.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>

                <category android:name="com.iamplus.onenumber.device"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

将合并的模块:

分级:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion '25.0.0'

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            jniDebuggable true
        }
    }
}

dependencies {
    compile project(path: ':android-infra')
    compile 'com.sensiya:sense-services-client:1.24.2@aar'
    compile project(path: ':engine-core-server')
    compile project(path: ':engine-core-aneeda')
}

清单:

<manifest package="com.iamplus.android.senseServices"
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">

    <application
        tools:node="replace">
        <service
            android:name="com.iamplus.senseServices.ContextualEventService"
            android:enabled="true"/>

        <service
            android:name="com.iamplus.senseServices.Serv"
            android:enabled="true"/>

        <service
            android:name="com.iamplus.senseServices.Serv1"
            android:enabled="true"/>
    </application>    
</manifest>

有什么建议吗?

【问题讨论】:

  • 控制台没有登录?没有错误?
  • 绝对没有...
  • 你能分享你的应用gradle文件吗?
  • 不是真的有一些依赖文件,我能提供什么具体的吗?
  • 您是否尝试过 Gradle Clean 和 android studio '使缓存无效并重新启动'。如果之前存在冲突,则可能只是缓存问题

标签: android android-studio android-gradle-plugin android-manifest


【解决方案1】:

可能有很多事情。由于您没有提供代码,我猜您正在使用默认的合并行为。更多信息请见:Merge conflict heuristics

您可以使用Merged Manifest view 预览合并清单的结果并查找冲突错误。

一般来说,默认情况下合并应该可以工作。然后只需使用 Merged Manifest 视图 即可查看在合并过程中丢失值的方式和位置。使用Merge rule markers 将帮助您通过分配规则标记来管理合并。

如果根本没有合并。所以这可能是模块之间的依赖问题。

请注意,依赖顺序对于具有相同优先级的模块(例如库)起着至关重要的作用。

--- 2017 年 4 月 5 日更新 ---

这里有一些有用的提示:

  1. 尽量更新和重建其他库。
  2. 删除所有依赖项,然后清理项目,然后再次添加它们。和 检查您是否正确导入它们。这可以通过毫无问题地构建项目来完成。
  3. 请注意,由于模块中的 gradle 2.2.0 资产将无法访问 在应用中。
  4. 如果合并过程没有被属性明确禁用,请检查您的清单: tools:node=”remove"tools:node="removeAll" 或在 gradle 中(见 这个Disable Manifest Merger in Android Gradle Build)
  5. 尝试创建一个带有模块和轨道合并的演示。然后匹配 输出到您的项目。这将表明不是 配置问题,但 Android Studio 2.3(然后重新安装全新 版本)

--- 更新(2) 5.April.2017 ---

添加代码后,我可以看到您正在使用属性

tools:node="replace"

在模块中的应用程序元素下(也可能在应用程序的清单中)。我认为这就是为什么您没有从合并到应用程序清单的导入模块中合并任何清单的原因。请参阅tools:node="replace" 下的Node markers

完全替换优先级较低的元素。也就是说,如果有一个 低优先级清单中的匹配元素,忽略它并使用 此元素与此清单中显示的完全相同。

这意味着上面的两个模块永远不会将任何东西与清单合并:

  • android-infra
  • com.sensiya:sense-services-client:1.24.2
  • 引擎核心服务器
  • engine-core-aneeda

所以去掉那个属性,清理和重建模块。然后重建整个项目。

【讨论】:

  • 这似乎是迄今为止最好的方法。我不知道合并视图...我会尽快检查并回发
  • 1.试过了,没有。 2.试过了,没有。 3.已知。 4.不退出。 5.这与工作室版本无关,这也发生在使用gradle从其他计算机从命令行构建时......所以???
  • 添加了替换以试图解决该问题,这是无关紧要的,因为具有替换的一个模块合并而另一个不合并。我们尝试创建另一个显示该问题的项目,但无法重现它。我们尝试从所有子模块中的应用程序标签中删除所有标志,我们无法将其合并... Android 插件深处隐藏了一个错误,我们无法放置它
  • 感谢link。在我的情况下,AS 在合并视图中显示了 AndroidManifest,但两个底部选项卡(TextMerged Manifest)消失了。我重新打开AS,它在正常视图中显示了AndroidManifest。
【解决方案2】:

如果您遇到清单合并冲突,您有两种选择。

1) 查找项目中包含的所有清单文件,包括作为依赖项的库中的清单文件,并确保没有冲突的配置。

或 2) 向您的清单添加一些合并解决规则,以指示应如何解决每个冲突。

这里有一个很棒的页面,其中包含许多详细信息。
https://developer.android.com/studio/build/manifest-merge.html

【讨论】:

  • 没有冲突,没有 gardle 控制台错误或警告消息,只有当我手动将组件复制到应用程序清单中时,它才会真正将它们添加到最终清单中
【解决方案3】:

来自 Android Studio

构建 ---> 清理项目
然后
构建 --> 制作项目
这应该有助于修复

【讨论】:

    【解决方案4】:

    Unity 也有类似的问题。我能够通过使用 SDK 管理器并删除最新的 android api 来解决它。然后我安装了一个稍旧的 api 并且它可以工作(我认为是 API 21 或 22)

    What the SDK Manager looks like

    【讨论】:

      【解决方案5】:

      我最近在生产代码中遇到了同样的问题。 将一个库放入应用程序模块中也存在于其他 Gradle 依赖项中会导致重复条目。 我们需要从冲突的模块或库中排除此类模块或库。

      为此,我们必须知道特定 Gadle 依赖项使用的库数量。

      考虑我在我的应用程序 gradle 中使用“bolts-android-1.2.0.jar”的情况。 在同一个 gradle 中,我正在使用 facebookSDK,如下所示。

      compile('com.facebook.android:facebook-android-sdk:4.5.0')
      

      所以我必须排除“bolts-android”,如下所示

      compile('com.facebook.android:facebook-android-sdk:4.5.0') {
              exclude module: 'bolts-android'
          }
      

      那么如何知道facebookSDK使用的是“bolts-android”

      这里可以使用插件 Android Method Count

      【讨论】:

        【解决方案6】:

        似乎问题出在application 元素中使用tools:node="replace"。来自documentation

        ...如果低优先级清单中有匹配的元素,请忽略它并完全按照此清单中显示的方式使用该元素。

        您真正想要使用的是tools:node="merge",这是默认行为。

        在没有冲突时使用合并冲突启发法合并此标记中的所有属性和所有嵌套元素。这是元素的默认行为。

        【讨论】:

        • 我希望我能对此进行测试...该代码不再对我可用
        猜你喜欢
        • 2012-12-05
        • 2016-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-20
        相关资源
        最近更新 更多