web-dev-qa-db-ja.com

Androidビルドはライブラリのマニフェストをマージしません

多くのAndroid libモジュールに応じて、複数のプロジェクトがあります。アプリマニフェストでのxmlタグの重複を避けるために、関連するレシーバー、サービス、アクティビティをそれぞれのモジュールに配置します。

今日まで、私たちは以下を使用しました:

  • Android Studio:2.2.1
  • gradle:2.1.3
  • buildToolsVersion:23.0.3

本日、次のように更新しました。

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

この更新までは、すべてが正常に機能し、マニフェストがマージされ、競合が発生して修正されていました。私たちが行った更新の時点では、マニフェストはまったくマージされません!!

---アップデート1 ---

マージされたマニフェストビューを使用しましたが、マージにマニフェストが含まれていないことがわかりました。モジュールマニフェストからマージされるのは権限だけです。たとえば、に新しい権限を追加すると、モジュールは、それをマージするだけで、残りの要素はマージしないことを明示します!

Nothing to merge

マージするものがたくさんあることを保証します!

---アップデート2 ---

すべてoutsideメインマニフェストにマージされるアプリケーションタグであり、すべてwithinアプリケーションタグではないようです。

---アップデート3 ---

マージされないモジュール:

Gradle:

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>

マージするモジュール:

Gradle:

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>

助言がありますか?

12
TacB0sS

コードを提供しなかったので、デフォルトのマージ動作を使用していると思います。詳細については、以下を参照してください。 競合ヒューリスティックのマージ

マージされたマニフェストビュー を使用して、マージされたマニフェストの結果をプレビューし、競合エラーを見つけることができます。

一般に、デフォルトでマージが機能するはずです。次に、マージされたマニフェストビューを使用して、マージ中に値が失われた方法と場所を確認します。 マージルールマーカー を使用すると、ルールマーカーを割り当てることでマージを管理するのに役立ちます。

マージがまったくない場合。したがって、おそらくモジュール間の依存関係の問題です。

依存関係の順序は、ライブラリなど、同じ優先度レベルを持つモジュールで重要な役割を果たすことに注意してください。

---更新5.April.2017 ---

ここにいくつかの役立つヒントがあります:

  1. できるだけ他のライブラリを更新して再構築してみてください。
  2. すべての依存関係を削除してからプロジェクトをクリーンアップしてから、再度追加します。正しくインポートするかどうかを確認してください。これは、問題なくプロジェクトをビルドすることで実行できます。
  3. モジュールからのgradle2.2.0アセットは、アプリからアクセスできないことに注意してください。
  4. マージプロセスが属性によって明示的に無効にされていないかどうかをマニフェストで確認してください:tools:node=”remove"またはtools:node="removeAll"またはgradle(これを参照 Android Gradleビルド でマニフェストマージを無効にする)
  5. モジュールとトラックのマージを使用してデモを作成してみてください。次に、出力をプロジェクトに一致させます。これにより、構成の問題ではなく、Android Studio 2.3(したがって、新しいバージョンを再インストールする)であることが明確になります。

--- Update(2)2017年4月5日---

コードを追加した後、属性を使用していることがわかりました

tools:node="replace"

モジュールのアプリケーション要素の下(そしておそらくアプリのマニフェストにも)。これが、インポートされたモジュールからマージされたマニフェストがアプリのマニフェストにマージされなかった理由だと思います。見る tools:node="replace" under ノードマーカー

優先度の低い要素を完全に交換してください。つまり、優先度の低いマニフェストに一致する要素がある場合は、それを無視して、このマニフェストに表示されているとおりにこの要素を使用します。

つまり、上記の両方のモジュールは、次のマニフェストとマージされることはありません。

  • Android-インフラ
  • com.sensiya:sense-services-client:1.24.2
  • エンジンコアサーバー
  • engine-core-aneeda

その属性を取り除き、モジュールをクリーンアップして再構築します。次に、プロジェクト全体を再構築します。

8
Maher Abuthraa

マニフェストマージの競合が発生している場合は、2つのオプションがあります。

1)依存関係として持っているライブラリ内のマニフェストファイルを含め、プロジェクトに含まれているすべてのマニフェストファイルを見つけ、競合する構成がないことを確認します。

または2)いくつかのマージ解決ルールをマニフェストに追加して、各競合を解決する方法を指示します。

ここには多くの詳細が記載されたすばらしいページがあります。
https://developer.Android.com/studio/build/manifest-merge.html

2
Stephen

からAndroid Studio

ビルド--->クリーンプロジェクト
その後
ビルド->プロジェクトの作成
これは修正に役立つはずです

最近、製品コードで同じ問題が発生しました。アプリモジュールに1つのライブラリがあると、他の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メソッド数

0
Tarun Dholakiya

Unityでも同様の問題がありました。 SDK Managerに移動し、最新のAndroid apiを削除することで、問題を解決できました。次に、少し古いapiをインストールすると、機能しました(API 21または22だと思います)

SDKマネージャーの外観

0
Xertz

問題は、application要素でtools:node="replace"を使用していることが原因のようです。 ドキュメント から:

...優先度の低いマニフェストに一致する要素がある場合は、それを無視して、このマニフェストに表示されているとおりにこの要素を使用します。

実際に使用したいのは、デフォルトの動作であるtools:node="merge"です。

このタグのall属性と、すべてのネストされた要素がない場合はマージしますマージ競合ヒューリスティックを使用した競合。これは、要素のデフォルトの動作です。

0
guy.gc