Cómo generar múltiples apk (utilizando gradle, libGDX)

Lo intento

Quiero generar pocos APK (x86, armeabi-v7a). Para reducir el tamaño de APK en Google Play

Pero no funciona. Android studia dice import com.android.build.OutputFile – No se puede resolver el símbolo 'OutputFile'. Y en la consola que veo. Intento buscar en google otras instrucciones y traté de hacer algo al respecto yo mismo, pero no soy bueno en gradle

Error:Cannot invoke method multiply() on null object

Mi gradle-archivo es

 // map for the version code ext.versionCodes = ['armeabi-v7a':1, 'armeabi':2, 'x86':3] import com.android.build.OutputFile android.applicationVariants.all { variant -> // assign different version code for each output variant.outputs.each { output -> output.versionCodeOverride = project.ext.versionCodes.get(output.getFilter(OutputFile.ABI)) * 1000000 + android.defaultConfig.versionCode } } android { buildToolsVersion "20.0.0" compileSdkVersion 20 sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } instrumentTest.setRoot('tests') } defaultConfig { versionCode 11 versionName '1.3' } productFlavors { } splits { abi { enable true reset() include 'x86', 'armeabi-v7a', 'armeabi' universalApk true } } } // needed to add JNI shared libraries to APK when compiling on CLI tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -> pkgTask.jniFolders = new HashSet<File>() pkgTask.jniFolders.add(new File(projectDir, 'libs')) } // called every time gradle gets executed, takes the native dependencies of // the natives configuration, and extracts them to the proper libs/ folders // so they get packed with the APK. task copyAndroidNatives() { file("libs/armeabi/").mkdirs(); file("libs/armeabi-v7a/").mkdirs(); file("libs/x86/").mkdirs(); configurations.natives.files.each { jar -> def outputDir = null 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.jar")) outputDir = file("libs/x86") if (outputDir != null) { copy { from zipTree(jar) into outputDir include "*.so" } } } } 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.mygdx.crazyball.android/com.mygdx.crazyball.android.AndroidLauncher' } // sets up the Android Eclipse project, using the old Ant based build. eclipse { // need to specify Java source sets explicitely, SpringSource Gradle Eclipse plugin // ignores any nodes added in classpath.file.withXml sourceSets { main { java.srcDirs "src", 'gen' } } jdt { sourceCompatibility = 1.6 targetCompatibility = 1.6 } classpath { plusConfigurations += [project.configurations.compile] containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES' } project { name = appName + "-android" natures 'com.android.ide.eclipse.adt.AndroidNature' buildCommands.clear(); buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder" buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder" buildCommand "org.eclipse.jdt.core.javabuilder" buildCommand "com.android.ide.eclipse.adt.ApkBuilder" } } // sets up the Android Idea project, using the old Ant based build. idea { module { sourceDirs += file("src"); scopes = [COMPILE: [plus: [project.configurations.compile]]] iml { withXml { def node = it.asNode() def builder = NodeBuilder.newInstance(); builder.current = node; builder.component(name: "FacetManager") { facet(type: "android", name: "Android") { configuration { option(name: "UPDATE_PROPERTY_FILES", value: "true") } } } } } } } dependencies { } 

TL, DR:

Acabo de tener el mismo problema, y ​​para mí la respuesta es afortunadamente simple. En lugar de utilizar OutputFilter.ABI en la llamada a output.getFilter , utilice OutputFilter.FilterType.ABI :

 android.applicationVariants.all { variant -> variant.outputs.each { output -> def defaultCode = android.defaultConfig.versionCode def filter = output.getFilter(OutputFile.FilterType.ABI) def abiMultiplier = project.ext.versionCodes.get(filter) output.versionCodeOverride = abiMultiplier * 1000000 + defaultCode } } 

Lo que se rompió

Esto es esencialmente lo que tienes arriba, pero refactorizado en unas pocas líneas más. La diferencia clave está en la llamada a output.getFilter . Los ejemplos en los documentos dicen utilizar OutputFile.ABI – como de versiones de herramientas más recientes (no estoy seguro de cuál), esto es incorrecto. El argumento correcto es OutputFile.FilterType.ABI .

El método getFilter se define en la clase ApkVariantOutputImpl . Como se puede ver en el código fuente de ApkVariantOutputImpl , se necesita un único argumento de tipo OutputFile.FilterType ; OutputFile.ABI es una String , y Groovy (a pesar de todos los otros bits de magia que hace) evidentemente no convertir la cadena constante en el enum adecuado, resultando en un valor nulo.

Renuncia

Sólo FYI, tuve que cavar bastante extensivamente a través de diferentes versiones de las herramientas de construcción para encontrar el enlace de origen – parece que este ha sido un área de inestabilidad API. Esto funciona para mí, con las siguientes configuraciones:

 buildscript { dependencies { 'com.android.tools.build:gradle:1.2.2' } } android { compileSdkVersion 22 buildToolsVersion "22.0.1" // lots of stuff splits { abi { enable true reset() include 'x86', 'armeabi-v7a', 'mips' } } } 

Si desea construir un APK universal (con todas las diferentes ABI incluidas), tendrá que tener en cuenta el hecho de que la variante universal no tiene filtro ABI, es decir, comprobar el multiplicador de nulo y reemplazarlo por algo significativo como cero.

Parece que falla en un intento de obtener ABI para APK universal ya que no hay filtro para ello en su mapa de versionCodes . Debe comprobar el resultado de output.getFilter(OutputFile.ABI) antes de aplicar la multiplicación de alguna manera como por ejemplo:

 android.applicationVariants.all { variant -> // assign different version code for each output variant.outputs.each { output -> def abiFilter = output.getFilter(OutputFile.ABI) def abiMultiplier = 0 if (abiFilter != null) { abiMultiplier = project.ext.versionCodes.get(abiFilter) } output.versionCodeOverride = abiMultiplier * 1000000 + android.defaultConfig.versionCode } } 
  • Error GWT no resuelto en el proyecto LibGDX HTML
  • Libgdx app.exit () en Android no se cierra la aplicación
  • En libgdx en Android, ¿cómo puedo guardar el estado del juego en caso de que se muera la aplicación?
  • LibGDX leer archivo XML
  • Dibujar objeto personalizado curvado en LIBGDX?
  • Libgdx para Android muestra negro antes de la pantalla principal
  • Crear gran Jar (escritorio) de android / escritorio gdx proyecto
  • Creando una cuerda lisa con un motor de la física del androide
  • Cómo cargar las fuentes del sistema en Libgdx? Principalmente para android. ¿Y cómo puedo obtener la lista de fuentes disponibles?
  • Tomar la captura de pantalla en libgdx
  • Los anuncios de Admob aparecen sólo después de la primera actualización
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.