ABI Split在NativeScript 2.3.0中失败

时间:2016-10-10 18:41:32

标签: android nativescript glade

我已经向普通小组寻求帮助,但大多数人都没有得到它的帮助。 我有一个巨大的问题荒谬的apk大小我的简单的应用程序。我使用@markosko nativescript过滤器将应用程序从17.2MB减少到14MB,即使nativescript-snapshot也无法帮助17MB发布版本。

我尝试在nativescipt文档中使用ABI拆分示例,但我注意到它正在尝试拆分但是glade使用相同的名称进行所有apks,所以我在app.glade中提出了这个

def tnsBuildMultipleApks=true;

android {  
    defaultConfig {  
        generatedDensities = []
        applicationId = "com.maliyo.oneclick"  
        versionCode Integer.parseInt("" + "1" + "0")
    }  
    aaptOptions {  
        additionalParameters "--no-version-vectors"  
    }
    if (Boolean.valueOf(tnsBuildMultipleApks)) {
        splits {
            abi {
                enable true
                reset()
                include  'armeabi', 'armeabi-v7a', 'x86', 'mips'
                universalApk true
            }
        }
    }
} 

def getDate() {
  def date = new Date()
  def formattedDate = date.format('yyyyMMdd')
  return formattedDate
}

// map for the version code that gives each ABI a value
ext.versionCodes = [
    'F0F1F2X86Debug':1, 'F0F1F2ArmeabiDebug':2, 'F0F1F2Armeabi-v7aDebug':3, 'F0F1F2MipsDebug':4,
    'F0F1F2X86Release':1, 'F0F1F2ArmeabiRelease':2, 'F0F1F2Armeabi-v7aRelease':3, 'F0F1F2MipsRelease':4
    ]

// For each APK output variant, override versionCode with a combination of
// ABI APK value * 100 + defaultConfig.versionCode
android.applicationVariants.all { variant ->
    // assign different version code for each output
    variant.outputs.each { output ->
        if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
            println("******************************************************")
            println(output);
            println(output.getVariantOutputData().getFullName())

            if (Boolean.valueOf(tnsBuildMultipleApks)) {
                def file = output.outputFile
                // version at the end of each built apk
                //output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + android.defaultConfig.versionName + "-" + getDate() + ".apk"))
                output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + output.getVariantOutputData().getFullName() + "-" + getDate() + ".apk"))
                output.versionCodeOverride =
                    //(assd++) * 100
                    project.ext.versionCodes.get(output.getVariantOutputData().getFullName(), 0) * 100
                    + android.defaultConfig.versionCode
            }
        }
    }
}
/**/

很好,它分裂但是我认为因为我在输出处破解了文件名,因为命名模式,adb无法找到将apk推送到设备或模拟器,也许只是说apk not found。 / p>

我尝试通过USB手动将相应的apk发送到设备,该应用已成功安装,但在启动画面后显示崩溃metadata/treeNodeStream.dat could not be loaded

更新

@ plamen-petkov非常感谢你们的贡献,我同意你们工作正常,当你们一个接一个地改变abi过滤器时。但是在我的app.gradle中,我设法成功构建了多个apks并进行了测试和确定。

但就像tns只是将appname-debug.apkappname-release.apk推送到adb。我可以用tnsBuildMultipleApks来切换这个分裂,也许当我还在测试时我可以将其关闭并使用tns run android当我想要进行最终构建并再次将其变为一个因为它可以正常工作{ {1}}

tns build android --release ....

2 个答案:

答案 0 :(得分:3)

如果您一次使用一个,ABI拆分会非常有用。这是一个例子:

android {  
...
    splits {
        abi {
            enable true
            reset()
            include  'armeabi-v7a'
        }
    }
...
}

生成的.apk文件只包含armeabi-v7a设备所需的库,因为它是上面ABI拆分配置中提到的唯一体系结构。可用的ABI是'{64}中指出的'arm64-v8a','armeabi-v7a','x86',所以你不能使用'armeabi'或'mips'架构。

此外,您不需要这一行:'universalApk true',因为它的作用是忽略拆分并制作一个包含所有提供的体系结构的.apk文件,而您想要相反。

您还可以关注documentation问题的进展,因为它会进一步减少.apk的大小。

希望这有帮助!

答案 1 :(得分:1)

这项工作对我来说非常好,现在生成apks和tns run android运行正常,谢谢。

    // Add your native dependencies here:

// Uncomment to add recyclerview-v7 dependency
//dependencies {
//  compile 'com.android.support:recyclerview-v7:+'
//}
import groovy.json.JsonSlurper //used to parse package.json

def tnsBuildMultipleApks=true;
String content = new File("$projectDir/../../app/package.json").getText("UTF-8")
def jsonSlurper = new JsonSlurper()
def appPackageJson = jsonSlurper.parseText(content)

android {  
    defaultConfig {  
        generatedDensities = []
        applicationId = appPackageJson.nativescript.id  
        versionCode = appPackageJson.version_code ?: 1
    }

    aaptOptions {  
        additionalParameters "--no-version-vectors"  
    }
    if (Boolean.valueOf(tnsBuildMultipleApks)) {
        splits {
            abi {
                enable true
                reset()
                include  'x86', 'armeabi-v7a', 'arm64-v8a'
                universalApk true
            }
        }
    }
}

// map for the version code that gives each ABI a value
ext.versionCodes = [
    'x86':1, 'armeabi-v7a':2, 'arm64-v8a':3
]

// For each APK output variant, override versionCode with a combination of
// ABI APK value * 100 + android.defaultConfig.versionCode
// getAbiFilter() not working for me so I extracted it from getFullname()
if (Boolean.valueOf(tnsBuildMultipleApks)) {
    android.applicationVariants.all { variant ->
        println(appPackageJson)
        println(android.defaultConfig.versionCode)
        println(android.defaultConfig.applicationId)

        def name
        def flavorNamesConcat = ""

        variant.productFlavors.each() { flavor ->
            flavorNamesConcat += flavor.name
        }
        flavorNamesConcat = flavorNamesConcat.toLowerCase()
        println(flavorNamesConcat)

        variant.outputs.each { output ->
            if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
                //You may look for this path in your console to see what the values are
                println("******************************************************")
                println(output); println(output.getVariantOutputData().getFullName())

                def abiName = output.getVariantOutputData().getFullName().toLowerCase().replace(flavorNamesConcat, "").replace(project.ext.selectedBuildType, "")
                println(abiName)


                def file = output.outputFile
                def versionCode = project.ext.versionCodes.get(abiName, 0);
                output.versionCodeOverride =
                    project.ext.versionCodes.get(abiName, 0) * 100
                    + android.defaultConfig.versionCode

                def apkDirectory = output.packageApplication.outputFile.parentFile
                println(output.outputFile.name)
                def apkNamePrefix = ""
                if(versionCode){
                    apkNamePrefix = output.outputFile.name.replace(".apk", "-" + abiName)
                }
                else {
                    apkNamePrefix = output.outputFile.name.replace(".apk", "")
                }

                if (output.zipAlign) {
                    name = apkNamePrefix + ".apk"
                    output.outputFile = new File(apkDirectory, name);
                }

                name = apkNamePrefix + "-unaligned.apk"
                output.packageApplication.outputFile = new File(apkDirectory, name);
            }
        }
    }
}