深踩Android Studio 缓存的坑及解决方法

本文记录的是今天在群里提到的昨天所踩的一个坑,有关 AndroidStudio 缓存的。

先说一下背景。

我负责的一个项目,对一个图表库有外部依赖。这个图表库是我在维护的,由于新功能在开发中,所以我就使用了 SNAPSHOT 版本发布到 OJO(oss.jfrog.org) 上。我在项目中刚更新了依赖,忽然想到还少几个 API,于是发布了 SNAPSHOT 版本。

故事就这样开始了。

这时候回到 AndroidStudio 再去 Sync Project with Gradle Files 肯定是拉不下来的。众所周知,Gradle 的缓存策略中,对于 SNAPSHOT 版本默认的缓存周期是 24 小时,也就是从我上次更新之后,24小时内都会使用上次的缓存。

不周知的也没关系,我在这里补充说明一下,在 Gradle 用户指南的依赖管理一章中,有提到 Gradle 对于动态版本和变化模块的缓存时间默认是 24 小时。

何为动态版本?你见过的像 3.+ 这种就是动态版本,它会取检查到的最高的版本号。又比如 latest.integration ,它也是动态版本。

而变化模块,就是像 0.2-SNAPSHOT 这种后面带 SNAPSHOT 的版本了。

这两者的区别就是,前者尽管你代码中的版本号写法不变,但实际上它仍然是去取仓库的最新版本。而后者它在仓库中的版本号还是一样,仍然是 xxx-SNAPSHOT ,但实际上这个版本所对应的内容已经变了。

这里再多说几句,缓存周期也是可以修改的,在 Gradle 用户指南中同样有详细说明,就是添加如下配置:

configurations.all {
  resolutionStrategy.cacheDynamicVersionsFor 10, 'minutes' // 动态版本
  resolutionStrategy.cacheChangingModulesFor 10, 'minutes' // 变化模块
}

只是这里我一开始就贪省事,在更新依赖懒得去改。

既然如此,那怎么办?把 ~/.gradle/caches 整个给干掉?

不不不,那样太小题大做。其实这个问题我早已遭遇过,并且对于“汉化”过一遍 Gradle 用户指南的我来说太简单了。命令行下执行:

./gradlew aTD --refresh-dependencies

这里啰嗦一下, aTD 是项目中一个 Gradle 任务的缩写,全名是 assembleTestingDebug ,其中 Testing 是项目里的一个 ProductFlavor 。这并不重要, 重点是后面的参数 --refresh-dependencies ,加上这个参数,表示强制刷新依赖。

但是回到 AndroidStudio 写代码,发现代码提示中新的 API 还是没有出来。看来是 Android Studio 没有更新。不过没关系,这事我也有经验。点开右边的 Gradle 面板,找到 androidDependencies 任务,右键, Create xxxxx Configuration ,然后在弹出的面板的 Arguments 一栏中输入前面提到的参数 --refresh-dependencies ,添加完,在运行那里选择它执行。

等执行完,按照几年前的经验,这时候应该出来了吧?

然而,实际上并没有。

这时候我忽然想起,我们公司在阿里云服务器上搭建了一个 maven 私服,去年的时候我在上面配置了对 OJO 的代理,这时候拉取的是私服上的版本,是它没有更新?

没关系,解决方法很简单,删!

于是我登录到 nexus 上,找到缓存的这个库,右键,整个版本删掉。删了服务器上的之后,还觉得不放心,于是再把 .gradle 里的缓存给找出来删掉,我当时应该是这样子的:

使用 nexus 搭建 maven 私服有几种好处,一是可以放公司内部的库;二是配置对其他 maven 仓库的代理,当有人去访问某一个依赖时它就会缓存下来,下次其他人再访问同一个依赖的话它就会直接取缓存,对于一些在国内访问不是很友好的仓库如 jcenter,能有效减少等待时间。当然如果公司内部局域网部署一个的话,提升效果会更显著。

最后再执行前面步骤。命令行中已经可以看到重新下载了这个依赖了,并且我也检查了 .gradle/caches/modules-2 下对应的源码 jar 包,确实是更新了。

再回到 Android Studio,发现依然没有更新。

这什么情况?

我疑惑了一下,心中一个声音响起:

啊(这里应读四声)!

这时候我想到了,新版的 Android Studio 为了提速,多了一层缓存:对于第三方依赖会把它们解压出来,放到 ~/.gradle/caches/transforms-1 目录中。

于是继续:

删!

find . -name "hichart*" |xargs rm -rf

然后再构建,让它重新缓存,这时候应该就可以了吧。

在 Android Studio 中执行了构建,然后发现它确实重新缓存了。但是——

悲剧就此发展,深坑就此塌陷!

这时候,我发现不单是新加的 API 没有出来,编辑器里有关这个库的代码全都变红了!尽管!项目还是能跑起来!当时的屏幕是这样的:

不对不对。咋回事?

这时候我又机智地想到,这里缓存的路径有包含 hash 作为名称的文件夹,更新了之后,hash 值也不同了,所以应该是哪里的索引没有对应上。于是找啊找,就在 transforms-1/metadata-1.1 中发现了一个叫 results.bin 的文件。再搜一下里面有没有包含那个库的内容:

cat results.bin| grep "hichart"

提示是二进制文件。哦,那就加个参数:

cat results.bin| grep -a "hichart"

结果出来了,果然有。那好,那就再删!

等等——我这时谨慎了一下,还是重命名一下好了。于是重命名,然后再执行构建,然后看到这个文件重新生成了,看起来正朝预料中的发展。然而,有关这个库的引用还是报错。

这时候的我陷入了一番沉思,再试其他方法:

  1. Sync with File System
  2. Sync Project with Gradle Files
  3. File -> Invalidate Caches / Restart

还是无效。带着郁闷,我下班了。

虽然这问题此刻表现得如此顽固,但是最终它还是被我解决了。

早上一来,我觉得我应该是有点急了,毕竟项目的开发时间由此被我拖多了一天了,但是作为一名有着一颗运维的心的程序员,自己踩陷的坑无论怎样也要把它踩平。

于是我开始往其他缓存方面上考虑,也没有去想合不合逻辑。我想到了 Gradle 在构建时会对一个任务的输入做快照,于是找到项目里的 .gradle/buildOutputCleanup 目录,删!

还不行,那就 .gradle/4.4 (当前使用的 Gradle 版本),删!

还不对,那就整个 .gradle ,删!

甚至, ~/.gradle/caches/transforms-1/ ,删!

依然不对,那就 Android Studio 的配置文件夹, ~/.AndroidStudio3.1 ,删!

删完重新打开 Android Studio 导入配置,这时候发现已经不是之前的问题了,你以为问题解决了吗?不!是问题升级了!这时候已经不是那个库报红了,而是所有引用第三方库的地方都报红了!!!尽管,还是可以运行起来!!

百般无奈之下,继续 google,看到的还是前面提到的 Invilate Cache 的方法。忽然在 Stackoverflow 中看到了一个看起来不是很常见的回答:

退出 Android Studio,删除所有的 .iml 文件以及 .idea 目录,打开 Android Studio 重新导入项目。

咦?这方法没试过。那就试试吧:

find . -name "*.iml" |xargs rm
find . -name ".idea" |xargs rm -rf

然后重新打开 Android Studio,点 Sync with File System ,这时候奇迹终于出来了,应该说,Android Studio 终于正常了,编辑器不报红了!

压抑着心中的万分激动,有着打破沙锅问到底精神的我,对此问题仍不放弃思考。

所以,究竟是什么原因呢?

我看了一下 .iml 文件,没什么异常。那就再看.idea 目录。

find .idea -type f |xargs grep "hichart"

结果如下:

原来是在 .idea/libraries 里会记录每一个第三方库的 classes, javadoc 以及 sources 所对应的路径。其中 classes 对应的正是前面所提到的 transforms-1 里的目录,同样也正如前面所说,其中包含的路径是有 hash 值的,更新了依赖之后,hash 值不同,新的缓存路径也就不同了,而这里还是用的原来被删的那个路径,找不到对应的文件当然编辑器里就提示 cannot resolve symbol 了。所以正确而直接的解决方案应该是删除 .idea/libraries/ 里对应该第三方库的 xml 文件让它重新生成,或者是直接修改该 xml 文件的内容,改为更新依赖之后的路径。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Eclipse NDK迁移到Android Studio的方法示例
  • 在启动栏制作android studio启动图标
  • Android Studio 3.0 Gradle 配置变更
  • Android Studio设置、改变字体和主题的方法
  • 使用Android studio编写一个小的jni程序
  • Android Studio 代码导航快捷键
  • Android Studio多工程引用同一个library项目配置的解决方法
  • Android Studio中Run按钮是灰色的快速解决方法
  • Android Studio 下载视频到本地
  • 详解Android Studio中Git的配置及协同开发
  • Android Studio配置内嵌JDK的方法
  • AndroidStudio 配置 AspectJ 环境实现AOP的方法
  • 详解如何在Android Studio中添加RecyclerView-v7支持包
  • Android Studio 一个工程打包多个不同包名的APK实例详解
  • android studio library 模块中正确引用aar的实例讲解
  • Android Studio中导入module的方法(简单版)
  • Android Studio 引用外部依赖时报错的解决方法
  • android项目从Eclipse迁移到Android studio中常见问题解决方法
(0)

相关推荐

  • 使用Android studio编写一个小的jni程序

     1.简单介绍一下NDK和JNI NDK:NDK是Native Development Kit的缩写,是Google提供的一套工具集,可以让你其他语言(C.C++或汇编)开发 Android的 JNI.NDK可以编译多平台的so,开发人员只需要简单修改 mk 文件说明需要的平台,不需要改动任何代码,NDK就可以帮你编译出所需的so库. JNI:JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++) 2.打开Android

  • Android Studio中Run按钮是灰色的快速解决方法

    首先是,在不同的AS中,gradle版本不同,下载的sdk版本不同,这些,都在gradle(Project.Models)相关代码里调过来就好.之前的文章里有说过. 经过调好gradle这些文件,AS已经可以built 成功后. 下一步,Run the application. 这时候,遇到问题:Run按钮灰色,失效. 点击Run旁边 Select Run/Debug Configuration按钮 选择 Edit Configuration,于是: 在model下拉框中选择app.如果下拉框中

  • android studio library 模块中正确引用aar的实例讲解

    今天对接一个海康监控的sdk,其中sdk 是以aar的形式提供的,并且我需要用到此aar的模块是个library.所以按照正常的在application模块中引入aar的方式一致报错,首先提示要关闭offline ,然后关闭了还是会提示错误.想了很久不明白.最终通过公司前辈的指导,正确的引入了aar. 1.除了和正常的aar的引入方式外,我们还需要在application所在模块的build.gradle文件中加入如下一段: repositories { flatDir { dirs 'libs

  • 详解Android Studio中Git的配置及协同开发

    一. Android Stutio配置git setting–>Version Control–>Git–>Path to Git executable中选择git.exe的位置,这个Stutio一般会默认配置好: 配置完路径后点击后面的Test按钮,出现下面提示框则表示配置成功: 二. 将项目分享到github 1. 设置github账号密码 打开Setting–>Version Control–>GitHub,填写完账号密码后,点击Test测试,如果连接成功会弹出如下提示

  • Android Studio设置、改变字体和主题的方法

    1.步骤:File >> settings >> Appearance & Behavior >>Appearance >> 来到修改界面 如下图所示:(Theme 主题修改 :Name 字体 :size 字号大小:其他的效果自己设置就可以看到,下图是其中的一种效果) 2.修改代码区域的字体,字号等设置 步骤:File >> settings >> Editor >>Colors & Fonts >&

  • android项目从Eclipse迁移到Android studio中常见问题解决方法

    (1)将Eclipse项目导入到Android studio 中出现9-patch image问题解决方法: 在build.gradle里添加以下两句: aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false 用来关闭Android Studio的PNG合法性检查的,直接不让它检查. (2)Android Studio 错误: 非法字符: '\ufeff' 解决方案|错误: 需要class, interface

  • Android Studio多工程引用同一个library项目配置的解决方法

    在使用Android Studio开发的时候,如遇到多个项目引用同一个library的情况时,会遇到在每个项目中都要有一套library的代码的情况,对于还在开发和维护中的Library需要频繁的修改,这对同步就很麻烦,为了解决这个问题,出现了下面的解决方案. 首先:新建一个类库工程,工程名为AppLibs.Dev. 在该类库中包含一个公共的类库appLibs的Module,Module下面的build.gradle配置如下: /** 声明是Android类库 */ apply plugin:

  • Android Studio 代码导航快捷键

    简评:作为一位 Android 开发者,Android Studio 肯定是每天都要打交道的,熟练掌握其中的快捷键等技巧可以提高我们不少的效率. 虽然,网上有着很多列出快捷键的文章,但只是简单的看一看快捷键和说明,很难让人理解和掌握.本篇文章就专注于代码间导航的快捷键,配合动图,希望能帮助你记忆. TL;DR 下面的快捷键都是在 mac 上,快捷键设置是 Mac OS X 10.5+: ⌘ + O : 查找类. ⌘ + ⌥ + O : 通过信息(symbol)查找. ⌘ + ⇧ + O : 查找

  • Android Studio 3.0 Gradle 配置变更

    多渠道打包变更 flavorDimensions "default" productFlavors { xxxx { dimension "default" } } productFlavors.all { flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name] } 更改打包命名及路径 android.applicationVariants.all { variant -> if (va

  • Android Studio 下载视频到本地

    最近在研究视频下载到本地的问题,像爱奇艺,腾讯视频,迅雷看看等等一些视频播放器,如果在一个播放器里面视频下载到一半用户退出App之后,再次登录从头开始,那么就太可悲了,所以在做视频音频类的项目时,要实现的一个功能就是断点续传,就是将用户下载的视频或者音频等以字节流的形式存入数据库,下次用户再次下载时,将继续上次数据库的接着下载,这样用户体验就会很好,也大大节省了成本. 好了废话不多说,开始今天的正题. 一.先上效果图 二.使用GreenDao我们需要导入依赖 1.以下在项目gradle依赖中添加

  • Android Studio配置内嵌JDK的方法

    今天发现JDK环境变量没有配置好. 我没有专门去下载java,在下载Android Studio时,会自带内嵌的JDK. 打开File-OtherSettings-DefaultProjectStructure,可看到AS已自动勾选Use embedded JDK,而且是官方推荐的做法. 以下是配置环境变量的操作. java 1.8以后就无需CLASSPATH环境变量了. 我们只需配置JAVA_HOME和PATH即可. JAVA_HOME C:\AndroidStudio\jre (JDK安装目

  • Android Studio中导入module的方法(简单版)

    1.把要导入成Mudle的项目修改成符合Library的格式 修改该项目中bulid.gradle文件中第一行代码 把 apply plugin: 'com.android.application' 修改为 apply plugin: 'com.android.library' 然后,修改AndroidManifiest.xml文件中配置信息,此处主要是把原来配置的项目Style等配置以及MainActivity配置删除,这样处理是为了防止重复.以下以一个我的Moudle文件的AndroidMa

  • 详解如何在Android Studio中添加RecyclerView-v7支持包

    一直知道RecyclerView可以代替ListView.GridView使用,听说功能很强大,但还没有去学习过.今天想学习,没想到还没开始便撞墙了.输入Recycler,只有这两个东西,没有提示RecyclerView,说明支持包中没有. 最后一番百度后,终于解决(真不敢想象没有网络的情况下,怎么开发.怎么解决问题). 1.打开SDK Manager,在Extras树下找到Android Support Library,下载好支持包.RecyclerView在v7-21版本就出来了.我这里不用

  • 在启动栏制作android studio启动图标

    https://www.linuxidc.com/Linux/2017-08/146066.htm 首先在~/bin/android-studio文件夹下新建一个Studio.desktop文件,并用gedit打开,然后将以下的内容复制进去并改动. [Desktop Entry] Name=AndroidStudio Type=Application Icon=你的AndroidStudio解压文件夹的绝对路径/android-studio/bin/studio.png Exec=sh 你的An

  • Eclipse NDK迁移到Android Studio的方法示例

    最近看一个NDK项目,因为源码使用Eclipse IDE写的,想把代码导入Android Studio使用,毕竟好用很多,使用AS导入后,第一个问题就是编码问题,项目之前竟然使用的是GBK编码.首先就是改变编码问题.我先在设置中将项目编码改为UTF-8,build结果显示一堆错误的乱码,在网上逛了一圈,找到解决方案. 编码 将AS右下角的UTF-8换成GBK. 跳出提示选择"reload",此时注释之类的乱码会显示正确. 右下角再选择UTF-8 跳出提示选择"convert&

  • Android Studio 一个工程打包多个不同包名的APK实例详解

    公司最近有个特别的需求,同一套代码,稍做修改(如包名不一样,图标不一样,应用名不一样等),编译出几个不同的应用.刚好用AS重构完项目,在网上查阅了一些资料,终于搞定!!在这记录一下. AS主要是利用gradle来实现这个需求的,具体做法如下: 修改app的build.gradle文件 假设我们同一套代码编译2个app:app1和app2 android { ... productFlavors { // app1 app1 { // 设置applicationId(这里很重要,两个相同appli

  • Android Studio 引用外部依赖时报错的解决方法

    Android Studio 在引用外部依赖时,发现一直无法引用外部依赖.刚开始以为是墙的问题,尝试修改Gradle配置,未解决问题. 最终发现原来是在Android Sudio安装优化配置时,将Gradle设置为了离线工作模式 解决方法: 只需打开File->Settings->Build,Execution,Deployment->Gradle->取消offline work勾选 总结 以上所述是小编给大家介绍的Android Studio报错Unable to resolve

  • AndroidStudio 配置 AspectJ 环境实现AOP的方法

    昨天看了一段android配置aspectj实现AOP的直播视频,就试着自己配置了一下,可能是因为我自己的AndroidStudio环境的问题,碰到了不少的坑(其实还是因为对gradle理解的不多),但总归是配置好了,就分享一下. 试了两种方式,不过项目下的build.gradle,没什么变化,直接看一下代码吧: build.gradle(项目下) buildscript { ext { //android appcompat支持库版本 androidSupportVersion = '26.1

随机推荐