项目涉及到了要加载framework.jar,需要将libs文件夹下的framework.jar的依赖在原生framework依赖之前加载,触及到知识盲区,学习并记录下来。
先在app/libs文件夹下添加jar包,如果没有libs文件夹自行创建。
加入进项目后右击需要添加的jar,选择add as library,这时可以看到项目正在同步,同步完成过后可以发现APP目录下的build.gradle中的dependencies依赖下,新添加了依赖项
implementation files('libs\\framework.jar')
我们需要将 implementation 改为 compileOnly,like this:
compileOnly files('libs\\framework.jar')
然后再这个文件中加上这么一段代码,这时候APP目录下的build.gradle中我们应该改动了这些:
android {
...
//加上这一块代码
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
incremental true
}
...
}
dependencies {
compileOnly files('libs\\framework.jar')
...
}
项目级的需要import 相关的依赖来保证不出错,我这边的编译器会爆红,但是不影响编译
添加在顶部
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
然后添加如下代码:
...
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile){
options.compilerArgs << '-Xbootclasspath/p:CnsDVR/libs/framework.jar'
}
}
tasks.withType(KotlinCompile).configureEach {
compilerOptions.jvmTarget = JvmTarget.JVM_1_8
}
}
...
如果你的jar包没问题,那么应该就可以用了,代码会爆红,但是不影响编译,我跑的时候因为同时加入了另外一个wifi.jar,并且有依赖冲突报了,duplicate class这个错误,部分错误日志如下:
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
> Duplicate class android.net.wifi.CoexUnsafeChannel found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.EasyConnectStatusCallback found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$Capabilities found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$ParcelableRttParams found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$ParcelableRttResults found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$ResponderCallback found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$ResponderConfig found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$RttCapabilities found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$RttListener found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
Duplicate class android.net.wifi.RttManager$RttParams found in modules jetified-framework (framework.jar) and jetified-wifi (wifi.jar)
这个问题可以由两种解决方式,一种是把包里面的重复的类删除掉重新压缩放进去,另一种呢就是在APP目录下的build.gradle中排除掉多余的文件,类似如下:
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
incremental true
}
//加上这一块代码
packagingOptions {
exclude 'com/android/internal/util/Preconditions.uau'
exclude 'com/android/internal/util/AsyncChannel.uau'
}
...
}
dependencies {
compileOnly files('libs\\framework.jar')
...
}
这样就可以使用了。
先复习下一些见名知意的方法
dependencies {
compileOnly files('libs\\framework.jar')
...
}
compileOnly 用于将库添加为编译时依赖项,但在运行时不需要。这通常用于那些仅在编译时需要的库,例如某些测试库或编译时注解处理器。而implementation 用于将库添加为运行时依赖项。这是最常见的依赖关系类型,当你需要一个库在运行时可用时,你会使用它。
packagingOptions {
exclude 'com/android/internal/util/Preconditions.uau'
exclude 'com/android/internal/util/AsyncChannel.uau'
}
排除了两个路径文件,避免依赖冲突
tasks.withType(KotlinCompile).configureEach {
compilerOptions.jvmTarget = JvmTarget.JVM_1_8
}
这里配置了Kotlin编译任务,设置其目标JVM版本为1.8。
在使用的时候我们用到了这部分代码:
gradle.projectsEvaluated {
tasks.withType(JavaCompile){
options.compilerArgs << '-Xbootclasspath/p:CnsDVR/libs/framework.jar'
}
}
这部分代码配置了Java编译任务。它为Java编译器提供了额外的命令行参数。这些参数指示Java虚拟机在启动时使用特定的类路径。
那么gradle.projectsEvaluated是什么呢?
gradle.projectsEvaluated 是一个Gradle的生命周期事件。在Gradle的构建生命周期中,有多个事件和阶段,每个阶段允许你执行或配置特定的任务。projectsEvaluated是这些事件之一。
当所有的项目都已经被评估,并且所有的build.gradle文件都已经被解析和执行后,projectsEvaluated事件就会被触发。换句话说,这是所有项目的配置阶段完成后的一个点。
为什么这个事件是有用的呢?
在某些情况下,你可能需要等待所有的项目配置完成后才能执行某些操作。例如,假设你有多个子项目,并且你想在主项目的build.gradle文件中对它们进行一些后处理或汇总操作。这样的操作可能依赖于所有子项目的配置信息,所以你需要确保在所有的项目都被评估后再执行这些操作。
在给出的代码示例中,gradle.projectsEvaluated被用来配置Java编译任务。这意味着只有当所有的项目都被评估后,这些Java编译的配置才会被应用。这可能是为了确保在配置Java编译选项之前,所有的其他插件或脚本都已经完成了它们的配置工作。
简而言之,gradle.projectsEvaluated为你提供了一个机会,在所有项目都被评估后执行某些操作或配置。
上面提到了Gradle的生命周期事件,那么Gradle的生命周期事件是什么呢?
Gradle的生命周期事件主要包括以下四个阶段:
此外,在Gradle的生命周期中,每个阶段都有对应的钩子函数(Hook Function),这些钩子函数可以在特定的阶段执行用户定义的代码。例如,在初始化阶段有settingsEvaluated
和projectsEvaluated
两个钩子函数;在配置阶段有beforeEvaluate
和afterEvaluate
两个钩子函数;在执行阶段有taskGraphReady
、taskExecutionStarted
、taskExecutionFinished
等钩子函数;在完成阶段有buildFinished
等钩子函数。通过使用这些钩子函数,你可以在Gradle生命周期的不同阶段执行自定义的操作,以满足特定的构建需求。
以上就是今天要讲的内容,本文仅仅简单介绍了Android gradle配置jar包加载顺序及延伸知识。