安卓 N - 尽管 minSDK 设为 14,但无法在较低 API 上运行

17

我试图将 APK 在更新 compileSdkVersion 到 N 后运行在 API 22 设备上,但无法实现。

compileSdkVersion 'android-N'
buildToolsVersion "24.0.0 rc1"

defaultConfig {
       minSdkVersion 14
       targetSdkVersion 'N'
}

输入图像描述

3个回答

17

默认情况下,构建工具设置为阻止您在旧设备上运行N开发者预览应用程序。据推测,这是谷歌试图防止人们基于预览构建的内容进行发布的一种懒散方式。这种方法也在过去的两个开发者预览版中使用过。因此,谷歌不希望您在Android 5.0(API级别22)设备上测试N开发者预览应用程序,以查看您是否正确处理了向后兼容性。

¯\_(ツ)_/¯

幸运的是,您可以通过黑科技解决:

android {
    compileSdkVersion 'android-N'
    buildToolsVersion "24.0.0 rc1"

    defaultConfig {
      minSdkVersion 15
      targetSdkVersion 'N'
    }

    // based on https://dev59.com/kYXca4cB1Zd3GeqPHFyc#27372806

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.processManifest.doLast {
                def manifestOutFile = output.processManifest.manifestOutputFile
                def xml = new XmlParser().parse(manifestOutFile)
                def usesSdk = xml.'uses-sdk'

                usesSdk.replaceNode{
                    'uses-sdk'('android:minSdkVersion': '15',
                               'android:targetSdkVersion': '15')
                }

                def fw=new FileWriter(manifestOutFile.toString())

                new XmlNodePrinter(new PrintWriter(fw)).print(xml)
            }
        }
    }
}

这些工具需要的是 targetSdkVersion 'N',这就导致你无法在旧设备上运行应用。所以,这段 Groovy 代码允许构建工具从 targetSdkVersion 'N' 开始,然后在打包前将另一个 targetSdkVersion 值替换为生成的清单文件中。在这种情况下,我将 minSdkVersiontargetSdkVersion 设置为 15,但你可以替换成自己的值。此外,你需要重新构建或清理项目才能使更改生效。

好的方面是,最终生成的应用可以安装并在旧版 Android 设备上运行(尽管可能仅限于通过命令行构建;我认为 Android Studio 不喜欢这种技巧)。

不足之处是,你的 targetSdkVersion 实际上并不是 N,这可能会影响一些 N 开发者预览设备上的行为。你可能想设置一个特定的构建类型,用于进行向后兼容性测试,并仅在该构建类型上使用我的修改清单文件技巧。然后,你可以在一个构建中同时进行正式的 N 开发者预览设置和某些向后兼容性测试。


1
我找到了一个有效的解决方案,但在此之前,先讲一点历史。我的做法是尝试创建不同版本的应用程序,每个版本都有自己的compileSdkVersion
以下是我的build.gradle文件中的代码片段。 第一次尝试(compileSdkVersion是特定于变体的)允许您仅在API级别>= ANDROID-N上安装应用程序
    //compileSdkVersion 'android-N'
    buildToolsVersion '24.0.0 rc1'

    productFlavors {
        dev {
            compileSdkVersion 23
            targetSdkVersion 23
        }
        experimental {
            compileSdkVersion 'android-N'
            minSdkVersion 'N'
            targetSdkVersion 'N'
        }
    }

第二次尝试(compileSdkVersion仍然是特定变量,但我已经删除了实验性变量):允许您仅在API Level < ANDROID-N上安装应用程序。
    //compileSdkVersion 'android-N'
    buildToolsVersion '24.0.0 rc1'

    productFlavors {
        dev {
            compileSdkVersion 23
            targetSdkVersion 23
        }
        /*
        experimental {
            compileSdkVersion 'android-N'
            minSdkVersion 'N'
            targetSdkVersion 'N'
        }
        */
    }

第三次尝试(compileSdkVersion仍然是特定于变量的,但在dev之前定义了experimental

//compileSdkVersion 'android-N'
buildToolsVersion '24.0.0 rc1'

productFlavors {
    experimental {
        compileSdkVersion 'android-N'
        minSdkVersion 'N'
        targetSdkVersion 'N'
    }
    dev {
        compileSdkVersion 23
        targetSdkVersion 23
    }
}

在我非常惊讶的情况下,这个方法起作用了!我不知道为什么,但确实有效。你需要在任何其他变量之前定义你的Android-N专用变量,在Android Studio中点击Build Variants并选择要编译的变量即可。
我将在Android-N错误跟踪器中提交一个问题,并在获取更多信息时更新此答案。

-1

如果不进行黑客攻击,你是无法完成它的。
这是N-Preview的限制,你必须仅使用此配置:

android {
  compileSdkVersion 'android-N'
  buildToolsVersion 24.0.0 rc1
  ...

  defaultConfig {
     minSdkVersion 'N'
     targetSdkVersion 'N'
     ...
  }
  ...
}

我不明白这个答案如何帮助我在低于 N 的 api 上运行项目。 - bongo
@bongo,如果不通过修改程序,你是无法做到的。这是Android团队选择的限制。我理解它并没有帮助,但这就是事实。你做不到。 - Gabriele Mariotti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接