欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

创建项目appcompat-v7:29.+报错终级解决办法(每次重建都不会报错!)

程序员文章站 2022-03-23 22:47:08
有时候兴高采烈的准备创建一个android项目,准备展示自己的一些奇怪的有创意的想法的时候,当你新建了一个空项目,却开始报错。那真是令人懊恼的事情。下面我们就来解决依赖com.android.support:appcompat-v7:29.+这个错误。以后重建项目也不会提示了!首先,安卓版本是3.2.1.如下图,因为不是这个版本可能不会报这样的错误。错误如下图Unable to resolve dependency for ':app@releaseUnitTest/compileClasspa...

有时候兴高采烈的准备创建一个android项目,准备展示自己的一些奇怪的有创意的想法的时候,当你新建了一个空项目,却开始报错。那真是令人懊恼的事情。
下面我们就来解决依赖com.android.support:appcompat-v7:29.+这个错误。以后重建项目也不会提示了!
首先,安卓版本是3.2.1.如下图,因为不是这个版本可能不会报这样的错误。
创建项目appcompat-v7:29.+报错终级解决办法(每次重建都不会报错!)
错误如下图
创建项目appcompat-v7:29.+报错终级解决办法(每次重建都不会报错!)

Unable to resolve dependency for ':app@releaseUnitTest/compileClasspath': Could not find any version that matches com.android.support:appcompat-v7:29.+. 

意思就是不能得到这个兼容库的依赖,原因很简单,目前还没有以296开头的依赖库版本。
可是,这一依赖库版本是怎么来的呢?细心的我们肯定会发现,这个29,不但出现在了dependencies闭包(gradle groovy里面的概念)里面。而且还出现在了android 闭包里面。如下

android { compileSdkVersion 29 buildToolsVersion '28.0.3' defaultConfig { applicationId "test.com.livetest" minSdkVersion 16 targetSdkVersion 29 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } 

可以看到,compileSdkVersion 属性,还有defaultConfig闭包里面的targetSdkVersion都使用了这个29。很明显,这个29就是你当前安装的android sdk的最新版本。所以,创建项目时候,默认使用了当前你安装的sdk的最新版本来创建的。当你明白了这些以后,我相信,问题已经难不倒你了,我们只要找到哪里使用了最新的sdk的属性,把他们相应的改变了,一切就解决了。
熟悉android studio的都知道,我们的项目是由gradle构建的,gradle指定了一些约束,才是我们的项目得以成为一个整体。然而,我们新建项目以后,里面的好多文件,例如build.gradle settings.gradle甚至.gitignore文件,这些文件是怎么生成的呢?答案是模板。模板定义了文件的不变内容,可变的,我们可以把它抽象为参数,使用模板时候直接传递参数进去,就生成了不同的文件。说了这么多,让我们先看一下我们所有模板的路径在哪?
打开这个文件夹

%Android Studio%\plugins\android\lib\templates 

简单一点这个就是你android studio的安装路径,然后一路找到templates文件夹,你就可以看到如下所示的文件结构
创建项目appcompat-v7:29.+报错终级解决办法(每次重建都不会报错!)
当然,我们要修改的肯定是gradle-projects文件夹里面的内容了。
直奔主题吧,找到

gradle-projects\NewAndroidModule\root\build.gradle.ftl 

顾名思义,这个文件定义了我们app的build.gradle模板,看这个文件的后缀名,ftl(freemarker template language)这个是freemarker的模板文件。freemarker就是专门定义模板的一种工具。
打开这个文件,

<#import "./shared_macros.ftl" as shared> <#import "root://activities/common/kotlin_macros.ftl" as kt> <#if isInstantApp> apply plugin: 'com.android.feature' <#else> <#if isLibraryProject> apply plugin: 'com.android.library' <#elseif isDynamicFeature> apply plugin: 'com.andorid.dynamic-feature' <#else> apply plugin: 'com.android.application' </#if> </#if> <@kt.addKotlinPlugins /> <@shared.androidConfig hasApplicationId=isApplicationProject applicationId=packageName isBaseFeature=isBaseFeature hasTests=true canHaveCpp=true canUseProguard=isApplicationProject||isBaseFeature||(isLibraryProject&&!isInstantApp)/> dependencies { ${getConfigurationName("compile")} fileTree(dir: 'libs', include: ['*.jar']) <#if !improvedTestDeps> ${getConfigurationName("androidTestCompile")}('com.android.support.test.espresso:espresso-core:${espressoVersion!"+"}', { exclude group: 'com.android.support', module: 'support-annotations' }) </#if> <@kt.addKotlinDependencies /> <#if isInstantApp||isDynamicFeature> <#if isBaseFeature> <#if monolithicModuleName?has_content> application project(':${monolithicModuleName}') <#else> // TODO: Add dependency to the main application. // application project(':app') </#if> <#else> implementation project(':${baseFeatureName}') </#if> <#else> <@shared.watchProjectDependencies/> </#if> } 

可以看到它引入了一个宏(macro)
@shared.androidConfig
然后我们直接找到这个文件,就在同目录下,打开

<#macro androidConfig hasApplicationId=false applicationId='' hasTests=false canHaveCpp=false isBaseFeature=false canUseProguard=false> android { compileSdkVersion <#if buildApiString?matches("^\\d+$")>${26}<#else>'${buildApiString}'</#if> <#if compareVersionsIgnoringQualifiers(gradlePluginVersion, '3.0.0') lt 0>buildToolsVersion "${buildToolsVersion}"</#if> <#if isBaseFeature> baseFeature true </#if> defaultConfig { <#if hasApplicationId> applicationId "${applicationId}" </#if> minSdkVersion <#if minApi?matches("^\\d+$")>${minApi}<#else>'${minApi}'</#if> targetSdkVersion <#if targetApiString?matches("^\\d+$")>${26}<#else>'${targetApiString}'</#if> versionCode 1 versionName "1.0" <#if hasTests> testInstrumentationRunner "${getMaterialComponentName('android.support.test.runner.AndroidJUnitRunner', useAndroidX)}" </#if> <#if canHaveCpp && (includeCppSupport!false)> externalNativeBuild { cmake { cppFlags "${cppFlags}" } } </#if> } <#if javaVersion?? && (javaVersion != "1.6" && buildApi lt 21 || javaVersion != "1.7")> compileOptions { sourceCompatibility JavaVersion.VERSION_${javaVersion?replace('.','_','i')} targetCompatibility JavaVersion.VERSION_${javaVersion?replace('.','_','i')} } </#if> <#if canUseProguard> <@proguard.proguardConfig /> </#if> <#if canHaveCpp && (includeCppSupport!false)> externalNativeBuild { cmake { path "CMakeLists.txt" } } </#if> } </#macro> 

这时候我们可以清楚的看到了compileSdkVersion还有targetSdkVersion,把他们的引用变量改为一个数值,如我上面的代码(实际情况根据你的sdk定义,只要不是29)。
当你像我一样改了以后,你就完成了一半了,还有一个dependencies改了,就没事了。
如下,此文件在上一层目录,recipe.xml.ftl

<?xml version="1.0"?> <recipe> <mkdir at="${escapeXmlAttribute(projectOut)}/libs" /> <mkdir at="${escapeXmlAttribute(resOut)}/drawable" /> <merge from="root/settings.gradle.ftl" to="${escapeXmlAttribute(topOut)}/settings.gradle" /> <instantiate from="root/build.gradle.ftl" to="${escapeXmlAttribute(projectOut)}/build.gradle" /> <instantiate from="root/AndroidManifest.xml.ftl" to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" /> <#if hasInstantAppWrapper> <instantiate from="root/res/values/strings.xml.ftl" to="${escapeXmlAttribute(baseFeatureResOut)}/values/strings.xml" /> <#else> <instantiate from="root/res/values/strings.xml.ftl" to="${escapeXmlAttribute(resOut)}/values/strings.xml" /> </#if> <instantiate from="root/test/app_package/ExampleInstrumentedTest.${ktOrJavaExt}.ftl" to="${escapeXmlAttribute(testOut)}/ExampleInstrumentedTest.${ktOrJavaExt}" /> <#if unitTestsSupported> <instantiate from="root/test/app_package/ExampleUnitTest.${ktOrJavaExt}.ftl" to="${escapeXmlAttribute(unitTestOut)}/ExampleUnitTest.${ktOrJavaExt}" /> <dependency mavenUrl="junit:junit:4.12" gradleConfiguration="testCompile" /> </#if> <#if improvedTestDeps> <dependency mavenUrl="com.android.support.test:runner:+" gradleConfiguration="androidTestCompile" /> <dependency mavenUrl="com.android.support.test.espresso:espresso-core:+" gradleConfiguration="androidTestCompile" /> </#if> <#if !createActivity> <mkdir at="${escapeXmlAttribute(srcOut)}" /> </#if> <#if !backwardsCompatibility??> <dependency mavenUrl="com.android.support:appcompat-v7:26.+" /> <#else> <dependency mavenUrl="com.android.support:appcompat-v7:26.+" /> </#if> <#if makeIgnore> <copy from="root://gradle-projects/common/gitignore" to="${escapeXmlAttribute(projectOut)}/.gitignore" /> </#if> <#include "root://gradle-projects/common/proguard_recipe.xml.ftl"/> <#if hasMonolithicAppWrapper> <mkdir at="${monolithicAppOut}" /> <instantiate from="root/monolithic-AndroidManifest.xml.ftl" to="${monolithicAppOut}/src/main/AndroidManifest.xml" /> <instantiate from="root/monolithic-build.gradle.ftl" to="${monolithicAppOut}/build.gradle" /> <#if makeIgnore> <copy from="root://gradle-projects/common/gitignore" to="${monolithicAppOut}/.gitignore" /> </#if> </#if> <#if hasInstantAppWrapper> <mkdir at="${instantAppOut}" /> <instantiate from="root/instantApp-build.gradle.ftl" to="${instantAppOut}/build.gradle" /> <#if makeIgnore> <copy from="root://gradle-projects/common/gitignore" to="${instantAppOut}/.gitignore" /> </#if> <mkdir at="${baseFeatureOut}" /> <instantiate from="root/baseFeature-AndroidManifest.xml.ftl" to="${baseFeatureOut}/src/main/AndroidManifest.xml" /> <merge from="root/baseFeature-ApplicationManifest.xml.ftl" to="${baseFeatureOut}/src/main/AndroidManifest.xml" /> <instantiate from="root/baseFeature-build.gradle.ftl" to="${baseFeatureOut}/build.gradle" /> <#if makeIgnore> <copy from="root://gradle-projects/common/gitignore" to="${baseFeatureOut}/.gitignore" /> </#if> <#elseif isInstantApp && !isBaseFeature> <merge from="root/baseFeatureDependency-build.gradle.ftl" to="${baseFeatureOut}/build.gradle" /> </#if> <#macro copyIconCommands destination> <#if buildApi gte 26 && targetApi gte 26> <#-- Copy adaptive-icons --> <copy from="root/res/mipmap-anydpi-v26/ic_launcher.xml" to="${destination}/mipmap-anydpi-v26/ic_launcher.xml" /> <copy from="root/res/drawable/ic_launcher_background.xml" to="${destination}/drawable/ic_launcher_background.xml" /> <copy from="root/res/drawable-v24/ic_launcher_foreground.xml" to="${destination}/drawable-v24/ic_launcher_foreground.xml" /> <copy from="root/res/mipmap-anydpi-v26/ic_launcher_round.xml" to="${destination}/mipmap-anydpi-v26/ic_launcher_round.xml" /> </#if> <#if buildApi gte 25 && targetApi gte 25> <@copyMipmap destination=escapeXmlAttribute(destination) icon="ic_launcher_round.png" /> </#if> <@copyMipmap destination=escapeXmlAttribute(destination) icon="ic_launcher.png" /> </#macro> <#macro copyMipmap destination icon> <copy from="root/res/mipmap-hdpi/${icon}" to="${destination}/mipmap-hdpi/${icon}" /> <copy from="root/res/mipmap-mdpi/${icon}" to="${destination}/mipmap-mdpi/${icon}" /> <copy from="root/res/mipmap-xhdpi/${icon}" to="${destination}/mipmap-xhdpi/${icon}" /> <copy from="root/res/mipmap-xxhdpi/${icon}" to="${destination}/mipmap-xxhdpi/${icon}" /> <copy from="root/res/mipmap-xxxhdpi/${icon}" to="${destination}/mipmap-xxxhdpi/${icon}" /> </#macro> <#if copyIcons> <#if !isLibraryProject> <@copyIconCommands destination=escapeXmlAttribute(resOut)/> <#elseif hasInstantAppWrapper || isBaseFeature> <@copyIconCommands destination=escapeXmlAttribute(baseFeatureResOut)/> </#if> </#if> <#if !isLibraryProject> <instantiate from="root/res/values/styles.xml.ftl" to="${escapeXmlAttribute(resOut)}/values/styles.xml" /> <#if buildApi gte 22> <copy from="root/res/values/colors.xml" to="${escapeXmlAttribute(resOut)}/values/colors.xml" /> </#if> </#if> <#if hasInstantAppWrapper || isBaseFeature> <instantiate from="root/res/values/styles.xml.ftl" to="${escapeXmlAttribute(baseFeatureResOut)}/values/styles.xml" /> <#if buildApi gte 22> <copy from="root/res/values/colors.xml" to="${escapeXmlAttribute(baseFeatureResOut)}/values/colors.xml" /> </#if> </#if> <#if includeCppSupport> <mkdir at="${escapeXmlAttribute(nativeSrcOut)}" /> <instantiate from="root/CMakeLists.txt.ftl" to="${escapeXmlAttribute(projectOut)}/CMakeLists.txt" /> <instantiate from="root/native-lib.cpp.ftl" to="${escapeXmlAttribute(nativeSrcOut)}/native-lib.cpp" /> </#if> </recipe> 

找到backwardsCompatibility那个if标签,然后改成我这个样子,

<#if !backwardsCompatibility??> <dependency mavenUrl="com.android.support:appcompat-v7:26.+" /> <#else> <dependency mavenUrl="com.android.support:appcompat-v7:26.+" /> </#if> 

版本号可以根据自己情况修改,这样修改完了以后,在重建项目就不会有这样的问题了。

本文地址:https://blog.csdn.net/aLLLiyyy/article/details/107754042