android12-targetsdk31报错Failed to install-write all apks

一、错误描述

本人用的红米手机,android12的版本,原来的targetsdk为30,在android studio上直接run到手机上调试正常,但是将targetsdk调整为31后,一直install不上去,最后300秒超时,报错如下:

Installation did not succeed.
The application could not be installed.List of apks:
[0] 'L:\xxx\app\build\outputs\apk\debug\app-debug.apk'
Installation failed due to: 'Failed to install-write all apks'

二、爬坑经历

在网上找了一圈,有一些解决方案,但是都不适用,如下

1. 打开usb调试、打开usb安装。(这些正常的开发都会打开的,而且30的版本都能安装成功,能没有打开吗)

2.手机内存空间满了,权限问题。(这些当然也不存在)

3.android版本问题。(30的能成功,这个自然也不存在)

三、问题分析

1.小米手机有个很坑的问题,开发的时候如果有版本系统适配错误,不会明确指出哪个第三方库、程序里面配置文件哪个地方错误,只会统一报一个错误(“Failed to install-write all apks”),所以,如果你用的是小米手机,就不要一直纠结这个错误找问题。

2.从"targesdk迁移31后报错"这个方向找问题,最终找到了一些实质可以解决的方案。

3.targetsdk从低版本迁移到31及以上后,程序改动比较大,并且第三方库也需要跟随改动。所以是件很麻烦的事情。

四、问题解决

以下是我的综合解决方案,不清楚到底是哪一条生效,哪一条没有生效,最终结果是综合生效,供大家借鉴,切勿生搬硬套,每个app每个环境都不一样。

1.开发者选项中usb调试、usb安装重开,miui优化开关关闭,重启手机

2.Android 12 自动适配 exported 深入解析避坑众所周知,从Android12开始,使用了TargetSDK31之后,四大组件如果使用了intent-filter,但是没显性质配置exportedApp将会无法安装,甚至编译不通过。比如启动的Activity就需要设置exported为true,至于其他组件是否设置为true则看它是否需要被其它应用调用。然而这个事情的状态是这样的:如果出现问题的AndroidManifest文件是你本地的,那手动修改即可;但如果出现问题的是第三方远程依赖,那就需要升级第三方依赖库为最新版本,要么用网上的一个脚本文件,运行的时候自动将其在清单文件中加入exported。

参考链接1:Android 12 自动适配 exported 深入解析避坑 - 思创斯聊编程

参考链接2:Android 12 快速适配要点 - 掘金

com.android.tools.build:gradle:4.0.0 以及其下版本用如下脚本

/*** 修改 Android 12 因为 exported 的构建问题*/
android.applicationVariants.all { variant ->variant.outputs.all { output ->output.processResources.doFirst { pm ->String manifestPath = output.processResources.manifestFiledef manifestFile = new File(manifestPath)def xml = new XmlParser(false, true).parse(manifestFile)def exportedTag = "android:exported"///指定 spacedef androidSpace = new groovy.xml.Namespace('http://schemas.android.com/apk/res/android', 'android')def nodes = xml.application[0].'*'.findAll {//挑选要修改的节点,没有指定的 exported 的才需要增加(it.name() == 'activity' || it.name() == 'receiver' || it.name() == 'service') && it.attribute(androidSpace.exported) == null}///添加 exported,默认 falsenodes.each {def isMain = falseit.each {if (it.name() == "intent-filter") {it.each {if (it.name() == "action") {if (it.attributes().get(androidSpace.name) == "android.intent.action.MAIN") {isMain = trueprintln("......................MAIN FOUND......................")}}}}}it.attributes().put(exportedTag, "${isMain}")}PrintWriter pw = new PrintWriter(manifestFile)pw.write(groovy.xml.XmlUtil.serialize(xml))pw.close()}}}

如果你的项目不复杂,或者用到的第三方的库不多,先查看manifest.xml文件底部的MergedManifest 这个tab里面的报错信息,如果有报错,那么可以手动的去修改manifest文件,将exported属性添加上去。

参考链接:Android12 依旧提示使用 intent-filter 需设置 android:exported 属性_Earliest-Mlr的博客-CSDN博客

3.修改targetsdk和buildtool版本号匹配,我的是(targetSdkVersion=31,compileSdkVersion=31,buildToolsVersion=31.0.0)

修改了版本号后,出现了报错,如下:

意思是31的构建工具已经损坏,重新卸载后安装还是报错。所以不是下载过程的问题。

修改两个文件名称。

(1)进入到自己SDK的目录;

(2)进入到build-tools\31.0.0,修改 d8.bat 文件,将其名字改为dx;

(3)进入到build-tools\31.0.0\lib目录,修改d8.jar文件,将其名字改为dx.jar

参考链接:关于安卓项目targetSdkVersion升级到31后报错问题_水很清的博客-CSDN博客

4.在此过程中,修改了build.gradle后,clean project、重启android studio、重启手机都需要,按需吧。

五、最后说一句

项目比较复杂,用到的第三方库又多,又用的是比较坑的小米手机作为调试机,导致搞了3天才搞好。心态有点崩,android studio说真心话,各种版本、组件、第三方库、gradle版本、androidx、merge manifest等等适配真心很稀烂,有一说一,欢迎拍砖。

先写到这,一是对问题的总结,一是对猿友有个借鉴参考。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部