如何使用gradle和save and collect在android studio中集成反射库
我的问题与github上的@ronmamo库有关,并将其集成到我的Android项目中,以动态访问从某个接口继承的所有类 我对gradle或maven不太熟悉,所以这对我来说是一个学习过程,但我遇到了一个障碍,不知道如何调试/找到这个问题的答案 正如@ronmamo所建议的,我希望在构建时生成一个包含所有扫描元数据的xml文件,并在以后的代码中使用它时让反射收集它: 虽然扫描可以很容易地在您的 应用程序-而且不会花费很长时间,有时这是一个好主意 将反射集成到构建生命周期中。简单的 Maven/Gradle/SBT/任何可以保存所有扫描数据的配置 在编译后将元数据转换为xml/json文件。后来呢, 您的项目正在启动,您可以让反射收集所有 并为您重新创建元数据,使其 在运行时可用,无需重新扫描类路径-从而减少 启动时间 我不确定自己是否完全理解在整个过程中这种“引导”发生的确切位置(在android应用程序生命周期等方面,甚至是构建时间?),因此我不确定调用Reflections.collect()的确切位置。目前,当用户到达程序中的某个点时,我会在我的应用程序中稍后的某个点调用它 从几篇stackoverflow文章和git自述文件中,我现在已经想到了:([…]表示删除了不相关的代码) build.gradle(模块:应用程序): build.gradle(项目:MyProject): 稍后在我的代码中(该类在某个点通过用户输入到达,而不是在应用程序启动时加载): 我知道生成的.xml文件驻留在进行构建的计算机上,我不确定这是否也会传输到android设备,所以我猜这就是为什么失败的原因。但是在我的android设备上传输和运行apk之前,我的Java代码在什么时候可以访问这个文件呢 我试过从不同的角度用多种不同的方式在谷歌上搜索,但我似乎找不到一个解决方案来让反射在Android上工作。我理解这里解释的原理,似乎最好在构建时在xml文件中生成信息,以便在运行时提供类信息。但是我怎样才能正确地设置它呢如何使用gradle和save and collect在android studio中集成反射库,android,gradle,reflection,android-gradle-plugin,Android,Gradle,Reflection,Android Gradle Plugin,我的问题与github上的@ronmamo库有关,并将其集成到我的Android项目中,以动态访问从某个接口继承的所有类 我对gradle或maven不太熟悉,所以这对我来说是一个学习过程,但我遇到了一个障碍,不知道如何调试/找到这个问题的答案 正如@ronmamo所建议的,我希望在构建时生成一个包含所有扫描元数据的xml文件,并在以后的代码中使用它时让反射收集它: 虽然扫描可以很容易地在您的 应用程序-而且不会花费很长时间,有时这是一个好主意 将反射集成到构建生命周期中。简单的 Maven/G
谢谢这里有一点鸡或蛋的问题需要解决
Reflections
API访问从src/main/java
反射
类由Gradle的构建脚本
类加载器加载src/main/java
中的类是在定义了buildscript
classloader之后编译的反射
。例如:
buildscript {
classpath 'org.reflections:reflections:0.9.11'
}
task doReflectyStuff {
dependsOn compileJava
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, null)
Configuration config = new ConfigurationBuilder("com.mypackage", classLoader)
Reflections reflections = new ReflectionsBuilder(config)
...
}
}
类似的问题请参见这里有一点鸡或蛋的问题需要解决
Reflections
API访问从src/main/java
反射
类由Gradle的构建脚本
类加载器加载src/main/java
中的类是在定义了buildscript
classloader之后编译的反射
。例如:
buildscript {
classpath 'org.reflections:reflections:0.9.11'
}
task doReflectyStuff {
dependsOn compileJava
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, null)
Configuration config = new ConfigurationBuilder("com.mypackage", classLoader)
Reflections reflections = new ReflectionsBuilder(config)
...
}
}
类似的问题请参见几天来,我一直在尝试在Android中使用Reflections,这就是我迄今为止所取得的成果。我在项目的build.gradle中创建了一个任务:
task myTask(dependsOn: compileJava) {
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = new ConfigurationBuilder()
.addClassLoader(classLoader)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("com.company.project")))
.addScanners(new SubTypesScanner(false))
Reflections reflections = new Reflections(config)
reflections.save("${sourceSets.main.output.classesDirs}/META-INF/reflections/mcommerce-reflections.json", new JsonSerializer())
}
}
dependencies {
classpath 'org.reflections:reflections:0.9.10'
}
afterEvaluate {
android.applicationVariants.each { variant ->
variant.javaCompiler.doLast {
// get JAR file that contains the classes
def collection = project.configurations.compile*.toURI().find { URI uri -> new File(uri).name.startsWith("startOfJarFileNameHere") }
URL[] urls = collection.collect {
println "Collecting classes using Reflections from " + it
it.toURL()
}
// collect all classes
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = org.reflections.util.ConfigurationBuilder
.build("package.name.of.interest.here")
.addClassLoader(classLoader)
.setUrls(urls)
org.reflections.Reflections reflections = new org.reflections.Reflections(config)
// save as JSON file into the assets folder
// (a) generate file for current debug or release build
reflections.save(
"${variant.javaCompiler.destinationDir}/../../assets/${variant.buildType.name}/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
// (b) always update fall-back file for debug (used when running app from Android Studio or IntelliJ)
reflections.save(
"${variant.javaCompiler.destinationDir}/../../../../src/debug/assets/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
}
}
}
稍后,在项目中的一个类上,我实例化了反射,就像在GitHub的示例中所做的那样(我使用Kotlin):
如果在终端上运行myTask,则构建成功,但我收到消息“给定扫描URL为空。在配置中设置URL”,我在Google中搜索了此消息,但没有找到任何有用的内容
我尝试了在gradle文件上配置反射的不同方法,但是当我收集它们时,我总是收到一个空实例
我希望我的答案对某些人有用。几天来,我一直在尝试在Android中使用Reflections,这就是我迄今为止所取得的成就。我在项目的build.gradle中创建了一个任务:
task myTask(dependsOn: compileJava) {
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = new ConfigurationBuilder()
.addClassLoader(classLoader)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("com.company.project")))
.addScanners(new SubTypesScanner(false))
Reflections reflections = new Reflections(config)
reflections.save("${sourceSets.main.output.classesDirs}/META-INF/reflections/mcommerce-reflections.json", new JsonSerializer())
}
}
dependencies {
classpath 'org.reflections:reflections:0.9.10'
}
afterEvaluate {
android.applicationVariants.each { variant ->
variant.javaCompiler.doLast {
// get JAR file that contains the classes
def collection = project.configurations.compile*.toURI().find { URI uri -> new File(uri).name.startsWith("startOfJarFileNameHere") }
URL[] urls = collection.collect {
println "Collecting classes using Reflections from " + it
it.toURL()
}
// collect all classes
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = org.reflections.util.ConfigurationBuilder
.build("package.name.of.interest.here")
.addClassLoader(classLoader)
.setUrls(urls)
org.reflections.Reflections reflections = new org.reflections.Reflections(config)
// save as JSON file into the assets folder
// (a) generate file for current debug or release build
reflections.save(
"${variant.javaCompiler.destinationDir}/../../assets/${variant.buildType.name}/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
// (b) always update fall-back file for debug (used when running app from Android Studio or IntelliJ)
reflections.save(
"${variant.javaCompiler.destinationDir}/../../../../src/debug/assets/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
}
}
}
稍后,在项目中的一个类上,我实例化了反射,就像在GitHub的示例中所做的那样(我使用Kotlin):
如果在终端上运行myTask,则构建成功,但我收到消息“给定扫描URL为空。在配置中设置URL”,我在Google中搜索了此消息,但没有找到任何有用的内容
我尝试了在gradle文件上配置反射的不同方法,但是当我收集它们时,我总是收到一个空实例
我希望我的答案对某些人有用。我就是这么做的:任务是在Android上为提供依赖项的类(即JAR文件内)使用反射。此解决方案适合我: top build.gradle:
task myTask(dependsOn: compileJava) {
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = new ConfigurationBuilder()
.addClassLoader(classLoader)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("com.company.project")))
.addScanners(new SubTypesScanner(false))
Reflections reflections = new Reflections(config)
reflections.save("${sourceSets.main.output.classesDirs}/META-INF/reflections/mcommerce-reflections.json", new JsonSerializer())
}
}
dependencies {
classpath 'org.reflections:reflections:0.9.10'
}
afterEvaluate {
android.applicationVariants.each { variant ->
variant.javaCompiler.doLast {
// get JAR file that contains the classes
def collection = project.configurations.compile*.toURI().find { URI uri -> new File(uri).name.startsWith("startOfJarFileNameHere") }
URL[] urls = collection.collect {
println "Collecting classes using Reflections from " + it
it.toURL()
}
// collect all classes
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = org.reflections.util.ConfigurationBuilder
.build("package.name.of.interest.here")
.addClassLoader(classLoader)
.setUrls(urls)
org.reflections.Reflections reflections = new org.reflections.Reflections(config)
// save as JSON file into the assets folder
// (a) generate file for current debug or release build
reflections.save(
"${variant.javaCompiler.destinationDir}/../../assets/${variant.buildType.name}/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
// (b) always update fall-back file for debug (used when running app from Android Studio or IntelliJ)
reflections.save(
"${variant.javaCompiler.destinationDir}/../../../../src/debug/assets/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
}
}
}
project build.gradle:
task myTask(dependsOn: compileJava) {
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = new ConfigurationBuilder()
.addClassLoader(classLoader)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("com.company.project")))
.addScanners(new SubTypesScanner(false))
Reflections reflections = new Reflections(config)
reflections.save("${sourceSets.main.output.classesDirs}/META-INF/reflections/mcommerce-reflections.json", new JsonSerializer())
}
}
dependencies {
classpath 'org.reflections:reflections:0.9.10'
}
afterEvaluate {
android.applicationVariants.each { variant ->
variant.javaCompiler.doLast {
// get JAR file that contains the classes
def collection = project.configurations.compile*.toURI().find { URI uri -> new File(uri).name.startsWith("startOfJarFileNameHere") }
URL[] urls = collection.collect {
println "Collecting classes using Reflections from " + it
it.toURL()
}
// collect all classes
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = org.reflections.util.ConfigurationBuilder
.build("package.name.of.interest.here")
.addClassLoader(classLoader)
.setUrls(urls)
org.reflections.Reflections reflections = new org.reflections.Reflections(config)
// save as JSON file into the assets folder
// (a) generate file for current debug or release build
reflections.save(
"${variant.javaCompiler.destinationDir}/../../assets/${variant.buildType.name}/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
// (b) always update fall-back file for debug (used when running app from Android Studio or IntelliJ)
reflections.save(
"${variant.javaCompiler.destinationDir}/../../../../src/debug/assets/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
}
}
}
Android上的Java代码:
InputStream iStream = getAssets().open("reflections/my-reflections.json");
Configuration config = ConfigurationBuilder.build().setSerializer(new JsonSerializer());
Reflections reflections = new Reflections(config);
reflections.collect(iStream);
Set<Class<? extends MyType>> myTypes = reflections.getSubTypesOf(MyType.class);
InputStream iStream=getAssets().open(“reflections/my reflections.json”);
Configuration config=ConfigurationBuilder.build().setSerializer(新的JsonSerializer());
反射=新反射(配置);
收集(iStream);
Set我就是这么做的:任务是在Android上为提供依赖项的类(即JAR文件内部)使用反射。此解决方案适合我:
top build.gradle:
task myTask(dependsOn: compileJava) {
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = new ConfigurationBuilder()
.addClassLoader(classLoader)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("com.company.project")))
.addScanners(new SubTypesScanner(false))
Reflections reflections = new Reflections(config)
reflections.save("${sourceSets.main.output.classesDirs}/META-INF/reflections/mcommerce-reflections.json", new JsonSerializer())
}
}
dependencies {
classpath 'org.reflections:reflections:0.9.10'
}
afterEvaluate {
android.applicationVariants.each { variant ->
variant.javaCompiler.doLast {
// get JAR file that contains the classes
def collection = project.configurations.compile*.toURI().find { URI uri -> new File(uri).name.startsWith("startOfJarFileNameHere") }
URL[] urls = collection.collect {
println "Collecting classes using Reflections from " + it
it.toURL()
}
// collect all classes
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = org.reflections.util.ConfigurationBuilder
.build("package.name.of.interest.here")
.addClassLoader(classLoader)
.setUrls(urls)
org.reflections.Reflections reflections = new org.reflections.Reflections(config)
// save as JSON file into the assets folder
// (a) generate file for current debug or release build
reflections.save(
"${variant.javaCompiler.destinationDir}/../../assets/${variant.buildType.name}/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
// (b) always update fall-back file for debug (used when running app from Android Studio or IntelliJ)
reflections.save(
"${variant.javaCompiler.destinationDir}/../../../../src/debug/assets/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
}
}
}
project build.gradle:
task myTask(dependsOn: compileJava) {
doLast {
URL[] urls = sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
}
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = new ConfigurationBuilder()
.addClassLoader(classLoader)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("com.company.project")))
.addScanners(new SubTypesScanner(false))
Reflections reflections = new Reflections(config)
reflections.save("${sourceSets.main.output.classesDirs}/META-INF/reflections/mcommerce-reflections.json", new JsonSerializer())
}
}
dependencies {
classpath 'org.reflections:reflections:0.9.10'
}
afterEvaluate {
android.applicationVariants.each { variant ->
variant.javaCompiler.doLast {
// get JAR file that contains the classes
def collection = project.configurations.compile*.toURI().find { URI uri -> new File(uri).name.startsWith("startOfJarFileNameHere") }
URL[] urls = collection.collect {
println "Collecting classes using Reflections from " + it
it.toURL()
}
// collect all classes
ClassLoader classLoader = new URLClassLoader(urls, ClassLoader.systemClassLoader)
org.reflections.Configuration config = org.reflections.util.ConfigurationBuilder
.build("package.name.of.interest.here")
.addClassLoader(classLoader)
.setUrls(urls)
org.reflections.Reflections reflections = new org.reflections.Reflections(config)
// save as JSON file into the assets folder
// (a) generate file for current debug or release build
reflections.save(
"${variant.javaCompiler.destinationDir}/../../assets/${variant.buildType.name}/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
// (b) always update fall-back file for debug (used when running app from Android Studio or IntelliJ)
reflections.save(
"${variant.javaCompiler.destinationDir}/../../../../src/debug/assets/reflections/my-reflections.json",
new org.reflections.serializers.JsonSerializer())
}
}
}
Android上的Java代码:
InputStream iStream = getAssets().open("reflections/my-reflections.json");
Configuration config = ConfigurationBuilder.build().setSerializer(new JsonSerializer());
Reflections reflections = new Reflections(config);
reflections.collect(iStream);
Set<Class<? extends MyType>> myTypes = reflections.getSubTypesOf(MyType.class);
InputStream iStream=getAsse