Мгновенная функция Android: в этом подходе есть что-то принципиальное?

1

Я пытаюсь заставить мое приложение собираться заново после обновления с плагина google gradle 3.1.4 до последней версии 3.2.1, и я думаю, что, может быть, что-то не так с подходом, который я использовал, чтобы заставить мой instantapp работать в первую очередь, поэтому я опубликуйте этот вопрос, чтобы отменить или подтвердить это, и в таком случае попросить другой подход.

Вкратце, мое приложение представляет собой игру с большим количеством графики в папке ресурсов. Чтобы вписать instantapp в ограничение в 10 мегабайт, установленное в Google Play, мне пришлось удалить некоторые из этих ресурсов, которые мне не понадобятся в текущей версии, а также те, которые имеют более высокое разрешение, сохранив остальные. Кроме того, у instantapp немного другой код, чем у установленного, поэтому я переопределил некоторые методы и классы там.

Кажется, что минимальный модуль com.android.instantapp не может содержать ресурсы и код, поэтому я создал промежуточный функциональный модуль, в котором они хранятся.

Итак, после большой борьбы (в основном с плагинами firebase и com.google.gms.google-services) я пришел к такому подходу, который в итоге сработал с версией 3.1.4 плагина gradle (com.android.tools. строить: Gradle: 3.1.4)

Изображение 174551

Единственная странная вещь в том, что мне пришлось установить флаг baseFeature для обоих модулей: android_instant_feature и android_common. Но это сработало, и я наконец-то смог опубликовать мгновенную версию своей игры, в то время как установленная версия тоже продолжала работать.

Теперь, как только я обновляюсь до версии 3.2.1 плагина google gradle, проблемы начинаются, даже если я ничего не меняю. Я получил много ошибок такого рода при попытке построить проект:

Unable to find a matching variant of project :android_common:
  - Variant 'debugApiElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
      - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Aar'.
      - Found org.gradle.usage 'java-api' but wasn't required.
  - Variant 'debugFeatureApiElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
      - Found com.android.build.api.attributes.VariantAttr 'debugFeature' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Feature'.
      - Found org.gradle.usage 'java-api' but wasn't required.
  - Variant 'debugFeatureRuntimeElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
      - Found com.android.build.api.attributes.VariantAttr 'debugFeature' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Feature'.
      - Found org.gradle.usage 'java-runtime' but wasn't required.
  - Variant 'debugRuntimeElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
      - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Aar'.
      - Found org.gradle.usage 'java-runtime' but wasn't required.
  - Variant 'releaseApiElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found incompatible value 'release'.
      - Found com.android.build.api.attributes.VariantAttr 'release' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Aar'.
      - Found org.gradle.usage 'java-api' but wasn't required.
  - Variant 'releaseFeatureApiElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found incompatible value 'release'.
      - Found com.android.build.api.attributes.VariantAttr 'releaseFeature' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Feature'.
      - Found org.gradle.usage 'java-api' but wasn't required.
  - Variant 'releaseFeatureRuntimeElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found incompatible value 'release'.
      - Found com.android.build.api.attributes.VariantAttr 'releaseFeature' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Feature'.
      - Found org.gradle.usage 'java-runtime' but wasn't required.
  - Variant 'releaseRuntimeElements':
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found incompatible value 'release'.
      - Found com.android.build.api.attributes.VariantAttr 'release' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' and found incompatible value 'Aar'.
      - Found org.gradle.usage 'java-runtime' but wasn't required.

После некоторой настройки скриптов gradle, включая удаление флага true baseFeature из модуля android_instant_feature, я получил более краткую ошибку, но не могу сказать, действительно ли мне лучше, чем раньше. Ошибка заключается в следующем:

Ожидаемая конфигурация ': android_instant_feature: debugFeatureCompileClasspath' должна содержать ровно один файл, однако она не содержит файлов.

И теперь я просто заблокирован здесь, не зная, что делать или где искать дальше, поэтому мне интересно, есть ли что-то принципиально некорректное с моим подходом, в первую очередь, так как я придумал это после некоторых проб и ошибок, и я не конечно, это хорошо, и в таком случае какой другой подход я мог бы использовать, который соответствует моим требованиям и требованиям Google, в зависимости от того, какие они есть.

Это мои файлы Gradle для этих модулей, согласно запросу @TWL. Я заменил реальный идентификатор приложения на com.myapp.id, остальное - именно то, что у меня есть, включая множество вещей для libGDX, которые я считаю неактуальными, хотя я предпочитаю оставить их там во имя точности:

android_common:

apply plugin: "com.android.feature"

configurations { natives }

android {
    baseFeature true
    compileSdkVersion 28
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }

        androidTest.setRoot('tests')
    }
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        sourceSets {
            all {
                manifest.srcFile "AndroidManifest.xml"
            }
        }
        multiDexEnabled true
    }
    buildTypes {
        release {
            setMinifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    buildToolsVersion '28.0.2'
    lintOptions {
        abortOnError false
    }
    dexOptions {
        jumboMode true
    }
}

dependencies {
    application project(':android')
    implementation project(':core')
    api 'com.android.support:multidex:1.0.3'
    implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
    implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
    natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi"
    natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
    natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
    natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86"
    natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86_64"
    implementation "com.android.billingclient:billing:$playBillingLibVersion"
    implementation "com.google.firebase:firebase-core:16.0.3"
    implementation "com.google.firebase:firebase-ads:15.0.1"

    implementation fileTree(include: ['*.jar'], dir: 'libs')
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.google.guava:guava:24.0-android'
}

task copyAndroidNatives() {
    file("libs/armeabi/").mkdirs();
    file("libs/armeabi-v7a/").mkdirs();
    file("libs/arm64-v8a/").mkdirs();
    file("libs/x86_64/").mkdirs();
    file("libs/x86/").mkdirs();

    configurations.natives.files.each { jar ->
        def outputDir = null
        if (jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
        if (jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
        if (jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
        if (jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
        if (jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
        if (outputDir != null) {
            copy {
                from zipTree(jar)
                into outputDir
                include "*.so"
            }
        }
    }
}

android_instant_feature:

apply plugin: "com.android.feature"

android {
//    baseFeature true
    buildToolsVersion "28.0.2"
    compileSdkVersion 28
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ["${project(':android_common').projectDir}/res"]
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }
    }
    defaultConfig {
        versionCode 4031
        versionName "4.1.2.1i"
        minSdkVersion 16
        targetSdkVersion 28
        multiDexEnabled true
    }

    dexOptions {
        jumboMode true
    }

    // Proguard configuration
    buildTypes {
        release {
            //minifyEnabled true will turn proguard ON
//            minifyEnabled true
            //proguardFiles let you add your own proguard rules ('proguard-project.txt') in this case, as its already created by gdx-setup
//            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
        }
        debug {}
    }


    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    productFlavors {
    }
    lintOptions {
        abortOnError false
    }
}

task run(type: Exec) {
    def path
    def localProperties = project.file("../local.properties")
    if (localProperties.exists()) {
        Properties properties = new Properties()
        localProperties.withInputStream { instr ->
            properties.load(instr)
        }
        def sdkDir = properties.getProperty('sdk.dir')
        if (sdkDir) {
            path = sdkDir
        } else {
            path = "$System.env.ANDROID_HOME"
        }
    } else {
        path = "$System.env.ANDROID_HOME"
    }

    def adb = path + "/platform-tools/adb"
    commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.marzoa.ruletafree/com.marzoa.ruletafree.AndroidLauncher'
}

dependencies {
    implementation project(":core")
    feature project(":android_common")
    api 'com.android.support:multidex:1.0.3'
    implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
    implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
    implementation "com.google.firebase:firebase-core:16.0.3"
    implementation 'com.google.android.gms:play-services-instantapps:16.0.0'

    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'

android_instant:

apply plugin: 'com.android.instantapp'

android {
    defaultConfig {
        applicationId "com.myapp.id"
        minSdkVersion 16
        targetSdkVersion 28
        multiDexEnabled true
    }
}

dependencies {
    implementation project(":android_common")
    implementation project(":android_instant_feature")
}

Android:

apply plugin: "com.android.application"
apply plugin: 'io.fabric' // Needed by crashlytics. DO NOT REMOVE.

android {
    buildToolsVersion "28.0.2"
    compileSdkVersion 28
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ["${project(':android_common').projectDir}/res"]
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }

        androidTest.setRoot('tests')
    }
    defaultConfig {
        applicationId "com.myapp.id"
        versionCode 4032
        versionName "4.1.2.1"
        minSdkVersion 16
        targetSdkVersion 28
        multiDexEnabled true
    }
    dexOptions {
        jumboMode true
    }
    // Proguard configuration
    buildTypes {
        release {
            //minifyEnabled true will turn proguard ON
            minifyEnabled true
            //proguardFiles let you add your own proguard rules ('proguard-project.txt') in this case, as its already created by gdx-setup
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    productFlavors {
    }
    lintOptions {
        abortOnError false
    }
}

task importPuzzles(type: Exec) {
    // TODO
}

task run(type: Exec) {
    def path
    def localProperties = project.file("../local.properties")
    if (localProperties.exists()) {
        Properties properties = new Properties()
        localProperties.withInputStream { instr ->
            properties.load(instr)
        }
        def sdkDir = properties.getProperty('sdk.dir')
        if (sdkDir) {
            path = sdkDir
        } else {
            path = "$System.env.ANDROID_HOME"
        }
    } else {
        path = "$System.env.ANDROID_HOME"
    }

    def adb = path + "/platform-tools/adb"
    commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.marzoa.ruletafree/com.myapp.id.AndroidLauncher'
}

dependencies {
    implementation project(":core")
    implementation project(":android_common")
    api 'com.android.support:multidex:1.0.3'
    implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
    implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
    implementation "com.android.billingclient:billing:$playBillingLibVersion"
    implementation "com.google.firebase:firebase-core:16.0.3"
    implementation "com.google.firebase:firebase-ads:15.0.1"
    implementation 'com.crashlytics.sdk.android:crashlytics:2.9.5'

    implementation fileTree(include: ['*.jar'], dir: 'libs')
}

// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'

Заранее большое спасибо!

Теги:
firebase
gradle
android-instant-apps

1 ответ

1
Лучший ответ

Спасибо за предоставление файлов gradle и похоже, что ваши зависимости gradle были перепутаны.

Модуль com.android.feature который содержит значение baseFeature true должен быть тем, в чьих зависимостях также содержатся как application project() и feature project(). Вот основная причина вашей ошибки:

Ожидаемая конфигурация ': ___: debugFeatureCompileClasspath' должна содержать ровно один файл, однако она не содержит файлов.

Таким образом, от того, что вы предоставили, похоже, что ваш application project() и feature project() отделены.

Чтобы это исправить, ваш "базовый" android_common должен быть:

application project(':android')
feature project(":android_instant_feature")

И ваша "неосновная особенность" android_instant_feature должна быть:

implementation project(':android_common)

Это не изменит общую структуру вашего проекта.

  • Ваше приложение com.android.application будет скомпилировано с библиотеками: core и android_common.
  • Ваш com.android.instantapp будет скомпилирован с помощью соответствующих приложений: android_common.apk и android_instant_feature.apk.

Теперь, почему это работало с 2x baseFeature раньше? Я не знаю, это не должно иметь...

Раньше была страница @https://g.co/instantapps, которая объясняла структуру мгновенных приложений, но вы можете сослаться на одну из моих предыдущих публикаций, которая касается ее, для обзора и ссылок: как я могу получить доступ к активность из другого функционального модуля

Примечание: я заметил, что у вас есть проект implementation project(":core") общий для всех ваших модулей (за исключением instantapp). Если это чисто библиотека типа com.android.library, вам не нужно настраивать ее так. Вы можете просто поместить его в свою базу как: api project(":core") и удалить все остальные ссылки в другом месте. Объявление его как api означает, что любой модуль, который также реализует базу, также будет подвержен этой зависимости. (Попробуйте, есть редкие случаи, когда это зависает в зависимости от того, какие другие библиотеки есть у вашего core, но попробуйте и посмотрите).

  • 0
    Бесконечно благодарен! Это работает. :) Чтобы добавить к вашему ответу, мне также пришлось изменить minSDKVersion, потому что у меня есть некоторые места с 15 и другие с 16, что, очевидно, является ошибкой и не связано с моими предыдущими проблемами. Еще раз большое спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню