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

Я пытаюсь заставить мое приложение собираться снова после обновления с плагина 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.build: Gradle: 3.1.4)

my current approach

Единственная странная вещь - это то, что мне пришлось установить флаг "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'

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

1 Ответ

0 голосов
/ 06 ноября 2018

Спасибо за предоставление файлов 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 будет скомпилирован с мгновенными apks приложения: 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, но попробуйте и посмотрите ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...