1.Project 项目目录下的build.gradle,
可以设置很多全局gradle的属性
以下是 ButterKnife 的 项目gradle,很多属性都可以查到
buildscript { ext.versions = [ 'minSdk' : 9, 'compileSdk' : 26, 'buildTools' : '26.0.0', 'supportLibrary': '25.3.0', 'androidPlugin' : '2.3.3', 'androidTools' : '25.3.0', 'kotlin' : '1.1.2-4', 'release' : '8.6.0', ] ext.deps = [ android : [ 'runtime' : 'com.google.android:android:4.1.1.4', 'gradlePlugin': "com.android.tools.build:gradle:${versions.androidPlugin}", ], 'support' : [ 'compat' : "com.android.support:support-compat:${versions.supportLibrary}", 'annotations': "com.android.support:support-annotations:${versions.supportLibrary}", 'test' : [ 'runner': 'com.android.support.test:runner:0.5', ], ], 'lint' : [ 'core' : "com.android.tools.lint:lint:${versions.androidTools}", 'api' : "com.android.tools.lint:lint-api:${versions.androidTools}", 'checks': "com.android.tools.lint:lint-checks:${versions.androidTools}", 'tests' : "com.android.tools.lint:lint-tests:${versions.androidTools}", ], javapoet : 'com.squareup:javapoet:1.9.0', javaparser : 'com.github.javaparser:javaparser-core:3.2.8', junit : 'junit:junit:4.12', truth : 'com.google.truth:truth:0.34', robolectric : 'org.robolectric:robolectric:3.4-rc2', compiletesting: 'com.google.testing.compile:compile-testing:0.11', 'auto' : [ 'service': 'com.google.auto.service:auto-service:1.0-rc3', 'common' : 'com.google.auto:auto-common:0.8', ], 'release' : [ 'runtime' : "com.jakewharton:butterknife:${versions.release}", 'compiler': "com.jakewharton:butterknife-compiler:${versions.release}" ], 'kotlin' : [ 'stdLibJre8': "org.jetbrains.kotlin:kotlin-stdlib-jre8:${versions.kotlin}", ] ] }
2.同上,项目 build.gradle 还有如下的指令
注意,此处不能写常规的 allprojects——————> 那样的话,疑似会把当前Project项目的 build.gradle也按照以下指令设置
直接结果就是报错:
method google() 找不到
method url 找不到
Project 和 Module 的build.gradle 的结构是形似的 , 但两者有着天差和地别,这点一定要注意了!
这里只有设置为 subprojectes (子目录,形同于 module ),才能跑得通
————————> 也是因此, butterknife (module形式导入主项目的) 才能跑得通。
subprojects { project -> group = GROUP version = VERSION_NAME repositories { mavenCentral() google() maven { url "https://plugins.gradle.org/m2/" } } if (!project.name.equals('butterknife-gradle-plugin')) { apply plugin: 'checkstyle' task checkstyle(type: Checkstyle) { configFile rootProject.file('checkstyle.xml') source 'src/main/java' ignoreFailures false showViolations true include '**/*.java' classpath = files() } afterEvaluate { if (project.tasks.findByName('check')) { check.dependsOn('checkstyle') } } } buildscript { repositories { mavenCentral() google() maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath deps.android.gradlePlugin classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}" classpath 'gradle.plugin.com.kageiit:lintrules:1.1.2' } } }
3.有时候,有些包 比如此处的
"com.android.tools.lint:lint-tests:24.2.1"
这样直接导进去,就会报错 ——————> 原因在于,这个统一的版本号 “24.2.1” 在另外3个孪生包,有这个特定版本。
但是 lint-tests 这个包,就是不存在这个版本。
此时就需要换一个邻近的 compile jar 版本了。
这里推荐两个网站,可以很方便的查 compile jar包的 版本大全:
http://maven.outofmemory.cn/com.android.tools.lint/
https://mvnrepository.com/artifact/com.android.tools.external.com-intellij/uast/162.2228.14
相比之下,第2个好用一点。搜索更精准,版本也更全。
此处要注意的是,搜素的时候 要记得把 ” – ” (减号)去掉,因为减号在搜索中,是一个特殊操作符。表示不包括后面那个关键字。(和Google是一样道理)
4.
全部按照原先的 项目 build.gradle 和 Module build.gradle 导入并一一核实后,
还可能会出现一个问题————————
有一些隐藏的包没有导到。
比如以下这几个:
import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.JavaRecursiveElementVisitor; import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiReferenceExpression;
到时候会飘红字,表示找不到这个包 或者 这个类。
这个时候,就应该明白,其实是这个包没有导进去。
那么我们应该这么做:
(1) Ctrl + 左键,点击 原版 ButterKnife 相同位置的代码的那个类或者那个包。
(2)然后可以在 Android Studio 结构目录里, External Libraries 里,找到 当前代码所在的 Jar包的名字。
如同———————— Jar包名 下划线 版本号
——————这样的形式。
然后,我们如果聪明一点的话,就知道按照上面那两个 查找 compile Jar 包的网址大全去搜索查找了。
然后,
在网址中,找到具体的包
进入包的详情信息,
下方有一排按钮 点击 Gradle按钮
就可以把下面这一行关键信息复制进来了
// https://mvnrepository.com/artifact/com.android.tools.external.com-intellij/uast
compile group: ‘com.android.tools.external.com-intellij’, name: ‘uast’, version: ‘162.2228.14’
复制进来后,
重新 sync , 可以看到遇到的这个问题, 就完全解决了。
5.还可能会碰到下面这个问题
提示这个Symbol 不存在:
Detector.JavaPsiScanner
这里的Symbol啊,这个意思,就是一个变量或者接口或者一个类的意思。
我们去原版的ButterKnife 项目中去找, 然后同样方法 Ctrl + 左键 点击进去,
同样可以 在 External Libraries 中找到相关信息。
然后还可以在上方 路径栏里, 看到所有的包信息。
在下方的代码栏里, 可以看到 JavaPsiScanner 其实是一个 类中的内部接口。
然后为什么会提示不存在呢?
我们回头去看,结果发现
我们自己
使用的compile 对应的这个 版本 , 其实 是 lint-api-24.2.1.jar
而原版ButterKnife项目,使用的这个版本是 ……25.3.0……
所以,为了再次验证一下,是版本不同,导致的类的结构的不同。
我们去 com————android——————tools——————lint——————detector——————api 下看一下。
24.2.1 果然没有这个特殊接口
25.3.0 果然有这个特殊接口
所以,真像就一清大白了。
直接在我们项目中,找到 使用 lint-api…….jar 的地方
Replace(手动替换)——————24.2.1——————25.3.0
然后重跑起来编译,就没有出现这个问题了。
6.将来会遇到的高级技巧
——————必定会在Github 制作自己的 compile Jar 包 代码仓库时,用到
这是第三方源码库的 代码仓库配置
【来源: UltimateRecyclerView】
ext { //Library configurations PUBLISH_GROUP_ID = 'com.marshalchen.ultimaterecyclerview' PUBLISH_ARTIFACT_ID = 'library' PUBLISH_VERSION = '0.7.3' VERSION_CODE = 26 //Application app_demo_versionCode = 26 app_demo_versionName = '1.7.3' IS_UPLOADING = project.getGradle().startParameter.taskNames.any { it.contains('bintrayUpload') } }
以上是一些 ext 的 properties 值。
7.记得处理以下语句
apply from: rootProject.file('gradle/gradle-artifactory-upload.gradle')
这类文件,是放在 Project 项目的 gradle文件里面的 .gradle 文件。
从第三方开源库里面找到,并且粘贴过去。
并要注意一些变量的在 gradle.properties 里面的处理。
8.其实,有一种非常土的方法。可能不屑于用,但放在这里记录一下。
————把所有 External Libraries 里面的 Jar包 提炼出来
————用 Zip 打开,
————修改相关文件。
————再用 Zip 打包。
————放回 app / libs 文件夹下。
————以后 用到第三方库,就直接用Jar包里面的包名。
优势就在于,非常方便,每个项目集成到一个 Jar 包。
而且,
Github 第三方源码库的仓库, 给的一般都是最完备的版本。
从中提取出可以跑起来的Module 虽然不难, 但还是要费点麻烦。
而这样,先 Compile —— 再 提取 Jar包 ———— 直接提取 Jar 包 ———— 修改了放回去,直接用 ————
的方式非常
简单直接。
但缺点也在于 没有多少可以秀 的地方。
续,艰难的跋涉,痛苦的尝试
9.
could not find method bintray
这句提示——————>是要去
(1)把
plugins { id "com.jfrog.bintray" version "1.7.3" id "com.github.dcendents.android-maven" version "1.5" }
中的
"com.jfrog.bintray"
以插件形式导入。
apply plugin: 'com.jfrog.bintray'
如果稍后,提示
Plugin with id ‘com.novoda.bintray-release’ not found
的话,
那么参照这篇文章
http://blog.csdn.net/chenguang79/article/details/
在Project项目下面,添加
dependencies {
classpath ‘com.android.tools.build:gradle:1.5.0’ //添加下面这行代码就OK了
classpath ‘com.novoda:bintray-release:0.3.4’
即可。
如果更进一步,出现这个结果 ”org.gradle.api.internal.component.usage“
Unable to load class ‘org.gradle.api.internal.component.Usage’
那么参照这篇文章
http://www.lovecoder.cn/1582.html
遇到 Unable to load class ‘org.gradle.api.internal.component.Usage’
在github上找到了解决方案,在这里记录一下。
Thanks,I have solved this problem! This problem appears because the gradle i used ‘s version is 3.4.1,and it is not compatible with the plugin ‘com.novoda:bintray-release:0.4.0’ ‘s gradle version,when i upgrade it to 0.5.0,it works.
是因为gradle 版本与 插件com.novoda:bintray不兼容,升级到0.0.5就可以解决了。
感谢https://github.com/zhihu/Matisse/issues/51
那么参照这篇文章:
classpath
‘com.novoda:bintray-release:0.3.4’
在 项目Project build.gradle 下面添加 上述 classpath 替换老版本即可。
10.以下就是令人异常痛苦的 老Boss 了。
‘com.squareup:javawriter’ 冲突
提示内容是
Error:Conflict with dependency 'com.squareup:javawriter' in project ':app'. Resolved versions for app (2.5.0) and test app (2.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
大体意思,
就是 在 正常App 中使用了 2.5.0 的包,
在 test App 中使用了2.1.1 的包。
我这边做了诸多排查和分析。
首先:
(1)在网上搜索 javawriter , 然后从结果中有一条得知, 是 javapoet 库里的一个子包。
参见
http://www.jianshu.com/p/ae0fa4761dd8 【生成Java源文件 (javawriter, javapoet, codemodel)】
然后:
(2)我在 我的项目Project 中, 用 Ctrl + shift + F ,进行全局搜索。
搜索关键词 为 javapoet
然后仅在
butterknife——gradle——plugin 中找到
compile 'com.squareup:javapoet:1.9.0'
然后我的解决问题之旅就开始了
(3)
我想了一下,有个 kotlinpoet 也和它眼熟,
于是也把 kotlinpoet 作为备选项。
在
https://mvnrepository.com/
中分别
搜索
javapoet
kotlinpoet
javawriter
三个 Jar 包。
找到3个版本。尝试分别导进去。
仍然报一样的错,说明未果。
经过思考之后,
开始整理思路。
(4)思路
javawriter
现存于 2.5.0 2.1.1 中。|
两个版本
javawriter
必定存在于 javapoet中
可能存于 kotlinpoet中
然后
进一步猜测
Javapoet 是否存在于
butterknife-lint 之中
permission-lint 之中
butterknife-compiler之中
butterknife-gradle-plugin 之中
结果
只存在于
butterknife-compile 【存在】
butterknife-gradle-plugin 【存在】
permission-processor【存在】
之中
进一步猜测
Kotlinpoet
结果同样只存在于
permission-processor【存在】
之中
(5)
开始检验
检验的方式,就是之前学的 批量分析 项目Project中 所有dependencies 依赖 的命令行神器
打开命令行 Terminal
输入
gradlew -q dependencies app:dependencies –configuration compile
然后。此时可能会报
google () 方法 错误。
说明此时, gradle 从 gradle-3.4 更改为 gradle-4.1 以达到解决 build.gradle —— Sync 时报错google()不存在的方法。
在
build.gradle 代码页,是可行的。
而在
Terminal 命令行页, 是不可行的。
因此,在开始分析之前
又要把 Setting——build gradle—— 里面的 gradle-4.1 改换回来成 gradle-3.4
此时,就能够正常分析了。
这时候,分析结果出来后
不出意料的话,应该是
只在 butterknife——gradle————plugin 的Module 下的 build.gradle 里
存在一个
com.android.tools.build: gradle : 2.3.3 包
这里面有一个 :gradle-core:2.3.3 包
再往里面,又有一个 :builder:2.3.3 包
在子子子包里面, 找到了 javawriter:2.5.0
这就是那个 2.5.0 的新版的包。
而找遍了整个 项目Project ,也找不到 2.1.1 的包
而后来才知道, 这个是个 indirect 非直接的内部 包, 是从 build.gradle 里找不到的。
参见这篇 详细介绍:
https://sites.google.com/a/android.com/tools/tech-docs/new-build-system/user-guide#TOC-Resolving-conflicts-between-main-and-test-APK
注意 关键内容在
【Resolving conflicts between main and test APK】
之下
这篇文章很重要
我们等会还要用到
此时直接插入正题
在采用了无数的方法
都无法解决 javawriter 2.5.0 和 javawriter 2.1.1 的问题之后。
我们终于在 Android Studio 的提示信息里, 找到了 链接 ,然后进入了上面那篇文章。
(6)
上面那篇文章。
大意是讲,
App 的Jar 包版本, 应该 和 Test app 的 Jar包版本 , 保持一致。
如果存在不一致,
那么在 最新的那个版本的App类型 (如test 或 正式版) 的 build.gradle 之下, 采用 compile 或者 androidTestCompile 形式,来实现 保持最新包在最顶上。
我反复的尝试了
compile testCompile androidTestCompile 三者
都试了一遍
能试的地方都试了一遍。
发现都不行。还是不行。问题没得到解决。还是报同样的错。
于是,陷入了 迷惘和纠结当中。
这时候,上面那篇文章,随手讲到的一个非常规的方式的链接,一行小字
拯救了这一切。
(7)
那行小字代表的链接如下:
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
大意如下
Examples:
apply plugin: 'java' //so that there are some configurations configurations.all { resolutionStrategy { // fail eagerly on version conflict (includes transitive dependencies) // e.g. multiple different versions of the same dependency (group and name are equal) failOnVersionConflict() // prefer modules that are part of this build (multi-project or composite build) over external modules preferProjectModules() // force certain versions of dependencies (including transitive) // *append new forced modules: force 'asm:asm-all:3.3.1', 'commons-io:commons-io:1.4' // *replace existing forced modules with new ones: forcedModules = ['asm:asm-all:3.3.1'] // add dependency substitution rules dependencySubstitution { substitute module('org.gradle:api') with project(':api') substitute project(':util') with module('org.gradle:util:3.0') } // cache dynamic versions for 10 minutes cacheDynamicVersionsFor 10*60, 'seconds' // don't cache changing modules at all cacheChangingModulesFor 0, 'seconds' } }
然后给到了以下方法:
Methods
failOnVersionConflict() |
In case of conflict, Gradle by default uses the newest of conflicting versions. However, you can change this behavior. Use this method to configure the resolution to fail eagerly on any version conflict, e.g. multiple different versions of the same dependency (group and name are equal) in the same Configuration. The check includes both first level and transitive dependencies. See example below: |
force(moduleVersionSelectorNotations) |
Allows forcing certain versions of dependencies, including transitive dependencies. Appends new forced modules to be considered when resolving dependencies. |
然后全面的转机就在其中出现了:
我的代码变成了这样子 (经过多次调试,找到的正确的格式和形态,记得要在 Module 的 build.gradle 的根目录下。)
configurations.all { resolutionStrategy { failOnVersionConflict() force 'com.squareup:javawriter:2.5.0' } }
然后上述的所有问题都得到解决了。
然后 javawriter 就再也没报过错。
然后以后报的错,就是
Error:A conflict was found between the following modules
com.google.guava:guava 18.0
com.google.guava:guava 17.0
这样的错误。
这样的错误,思路是一样的,而且哪怕有变化,反复试就是了。
比如,能用的解法如下:
如下
configurations.all { resolutionStrategy { failOnVersionConflict() force "com.android.tools.lint:lint-api:25.3.3" force 'com.google.guava:guava:18.0' } }
一切问题都可以去解决。
直到遇到了下面这个问题。。。。。。
一切都结束了。
testCompile "com.android.support:support-annotations:24.2.1"
和
compile 'com.android.support:support-annotations:25.3.0'
这就是根本性质上的问题了。 干死一切愚蠢的SDK制作者。尤其是阿里云短视频的Android制作者。
【完】今天的文章
手动导入很多第三方源码库的高级技巧是_哪里可以买软件源代码分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/60292.html