Android Studio——不会报错的build.gradle到底长啥样

⚠️注意:如果是冲着文章题目点进来的,直接拉到第三部分看

吐槽预警:本文有大量吐槽。

一、疯狂吐槽

这部分可以略看。

这两天博主考研成绩出来了,给中意很久的导师发了简历。简历中有一条说去年写了个APP,但是博主忘记apk文件放哪了。这不是到时候可能要展示嘛,所以打开当时的项目,打算重新生成一个apk,以便于实验室面试时给老师看。

然鹅,事情没有那么简单,我也不知道发生了什么,相同的项目打开后,我最害怕的事情发生了:

环境坏了……

无论是refresh还是rebuild,什么.pom无法加载、R被标红之类,网上常见的环境出错或者xml文件出错会有的报错,我这应有尽有。

显然,我离开去复习考研的100来天,我的电脑发生了诡异的事情,和考研初试结束花了很大力气修复考研前能运行的Tensorflow项目bug一样,我开始着手修复我这被红色波浪线严重污染的Android Studio小花园,还它一片绿水青山。

本文不会将网上常见的.pom文件无法下载的解决方法之类的答案再复制粘贴到此处,我仅记录我是怎么一步步完成修复工作的,也许有些解决方法出乎意料。如果你已经为AS项目构建濒临崩溃,看看这篇,也许一些细节能帮到你。

二、修复

浪费时间的第一天

第一个问题就十分dan疼,在点击gradle的refresh按钮后,疯狂提示我不能获取.pom文件。这个问题的网上答案几乎清一色地告诉你“在build.gradle(Project: YourProjectName)”中加上国内的源:

maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }

然并卵。不过关于源的问题确实是大问题,事实上,去年我解决源的问题时,曾将build.gradle(Project: YourProjectName)改成如下的熊样才解决问题:

buildscript {
    
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
//        maven { url "https://maven.google.com" }
        google()
//        jcenter()
        jcenter {
            url "http://jcenter.bintray.com/"
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
//        maven { url "https://maven.google.com" }
        google()
//        jcenter()
        jcenter {
            url "http://jcenter.bintray.com/"
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

我的build.gradle已经是完美的了,可是.pom的问题依旧存在。第一天一直在查这个问题,无果,然后到晚上的时候,我发现了一个哭笑不得的事情,我不慎用idea打开了之前用AS创建的项目。我抱着侥幸心里用AS重新打开了项目,发现红波浪线少了大半(要知道白天我几乎已经将idea的各种配置都改正了,但依旧有很多问题,这说明了本文的第一个经验:即便是idea和AS的配置(sdk、jdk、gradle等)相同,也不要随便用idea打开AS创建的项目)。

不过,.pom问题还是存在的。

哭笑不得的第二天

第二天继续打开项目,因为之前的热点有点卡,所以我换了个热点继续干活,却发现.pom文件的问题解决了。

……

经过检查发现是网络的问题。之前我用外地手机号开的热点,其只能用3G,更换后的热点是本地手机号开的,能用4G。

所以本文的经验二:添加国内源也无法获取.pom文件时,检查下自己的网络是不是有问题

这之后就是常规操作了,但有个地方需要注意,我res/layout/下的.xml文件中,有种情况build时会报这个错:

在这里插入图片描述
图中标蓝部分是问题根源,如果你被图中“Run tasks”前的感叹号吸引,那么你会错误地在意以下这个问题:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
	at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:748)
Caused by: com.android.build.gradle.tasks.ResourceException: Error: java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: AAPT2 error: check logs for details
	at com.android.build.gradle.tasks.MergeResources.doIncrementalTaskAction(MergeResources.java:392)
	at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:110)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
	at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:46)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
	... 32 more
Caused by: Error: java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: AAPT2 error: check logs for details
	at com.android.ide.common.res2.MergedResourceWriter.end(MergedResourceWriter.java:332)
	at com.android.ide.common.res2.DataMerger.mergeData(DataMerger.java:301)
	at com.android.ide.common.res2.ResourceMerger.mergeData(ResourceMerger.java:412)
	at com.android.build.gradle.tasks.MergeResources.doIncrementalTaskAction(MergeResources.java:381)
	... 48 more
	Suppressed: java.lang.RuntimeException: Some file processing failed, see logs for details
		at com.android.builder.internal.aapt.QueuedResourceProcessor.waitForAll(QueuedResourceProcessor.java:121)
		at com.android.builder.internal.aapt.QueuedResourceProcessor.end(QueuedResourceProcessor.java:141)
		at com.android.builder.internal.aapt.v2.QueueableAapt2.close(QueueableAapt2.java:104)
		at com.android.build.gradle.tasks.MergeResources.doIncrementalTaskAction(MergeResources.java:389)
		... 48 more
Caused by: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: AAPT2 error: check logs for details
	at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:503)
	at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:482)
	at com.google.common.util.concurrent.AbstractFuture$TrustedFuture.get(AbstractFuture.java:79)
	at com.android.ide.common.res2.MergedResourceWriter.end(MergedResourceWriter.java:327)
	... 51 more
Caused by: java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: AAPT2 error: check logs for details
	at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:503)
	at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:462)
	at com.google.common.util.concurrent.AbstractFuture$TrustedFuture.get(AbstractFuture.java:79)
	at com.android.builder.internal.aapt.v2.QueueableAapt2.lambda$compile$0(QueueableAapt2.java:136)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	... 1 more
Caused by: com.android.builder.internal.aapt.v2.Aapt2Exception: AAPT2 error: check logs for details
	at com.android.builder.png.AaptProcess$NotifierProcessOutput.handleOutput(AaptProcess.java:443)
	at com.android.builder.png.AaptProcess$NotifierProcessOutput.err(AaptProcess.java:395)
	at com.android.builder.png.AaptProcess$ProcessOutputFacade.err(AaptProcess.java:312)
	at com.android.utils.GrabProcessOutput$1.run(GrabProcessOutput.java:104)

这长度看着就吓人,希望各位不要像我一样走弯路。这个问题卡我半天,一度怀疑这项目是不是要从零开始重来一遍了,我差点都能想象到面试时老师问我:小伙纸,简历上的APP呢,拿出来展示下?

回到真正的问题根源,前面那张图中标蓝部分,双击之得到真正的错误根源:

error: not well-formed (invalid token).

然后我发现res/layout/下有一个.xml文件中有一处短波浪线,截取那一块的图片如下:
在这里插入图片描述
图中光标那一行删了就行了,不能在这个位置加注释。

三、不会报错的build.gradle长啥样

给大家两个版本,一个是复杂版,就是本文一直在吐槽的项目,排查无误后两个build.gradle分别是以下样子(含注释帮助理解):

版本一(复杂版)

// project的build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.umbrella.myapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
//这个模块的内容如果出问题,就自行下载,然后解压放置在Android sdk相对应的文件夹下
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.+'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    
//下面几行内容需要了自行下载放在指定文件夹中,是单元测试要用的东西,不需要可以删了。
// 网有点问题,如果靠程序自动下载始终会报无法下载的错(添加阿里源都没用,网上啥方法基本都试过了)
//    implementation 'com.github.User:Repo:Tag'
//    testImplementation 'junit:junit:4.12'
//    androidTestImplementation 'com.android.support.test:runner:1.0.1'
//    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

//上网看了些资料,基本确定appcompat-v7的版本要和compileSdkVersion的版本相对应,
// buildtool的版本要等于或者高于sdk的版本
//model的build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
//经过无数次修改的配置文件,添加了可用的源,解决了部分问题,
// 还有些文件还是下载不了,于是手动下载并放在指定的文件夹中(方法见app的build.gradle)

buildscript {
    
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
//        maven { url "https://maven.google.com" }
        google()
//        jcenter()
        jcenter {
            url "http://jcenter.bintray.com/"
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
//        maven { url "https://maven.google.com" }
        google()
//        jcenter()
        jcenter {
            url "http://jcenter.bintray.com/"
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

版本二(纯净版)

之所以叫纯净版,是因为这两个build.gradle是hello world APP的,当然刚创建好的项目会报错,需要修改build.gradle,以下是修改过的样子:

//project的build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {  // Android plugin repository,可在project structure中查看
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {  // Default library repository,可在project structure中查看
        repositories {
            maven { url 'http://repo1.maven.org/maven2' }
        }
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

// 1、 buildscript里是gradle脚本执行所需依赖,分别是对应的maven库和插件
// 2、 allprojects里是项目本身需要的依赖,比如我现在要依赖我自己maven库的toastutils库,那么我应该将maven {url ‘https://dl.bintray.com/calvinning/maven‘}写在这里,而不是buildscript中,不然找不到。
//
// The “buildscript” configuration section is for gradle itself (i.e. changes to how gradle is able to perform the build). So this section will usually include the Android Gradle plugin.
// The “allprojects” section is for the modules being built by Gradle.
// Oftentimes the repository section is the same for both, since both will get their dependencies from jcenter usually (or maybe maven central). But the “dependencies” section will be different.
// Usually the “dependencies” section for “allprojects” is empty since the dependencies for each module are unique and will be in the “build.gradle” file within each of the modules. However, if all of the modules shared the same dependencies then they could be listed here.
// model的build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.umbrella.myapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
//这个模块的内容如果出问题,就自行下载,然后解压放置在Android sdk相对应的文件夹下
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.+'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
//下面几行内容需要了自行下载放在指定文件夹中,
// 网有点问题,如果靠程序自动下载始终会报无法下载的错(添加阿里源都没用,网上啥方法基本都试过了)
//    implementation 'com.github.User:Repo:Tag'
//    testImplementation 'junit:junit:4.12'
//    androidTestImplementation 'com.android.support.test:runner:1.0.1'
//    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

//上网看了些资料,基本确定appcompat-v7的版本要和compileSdkVersion的版本相对应,
// buildtool的版本要等于或者高于sdk的版本

发布了36 篇原创文章 · 获赞 41 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/umbrellalalalala/article/details/87549244