gradle 如何从Android应用程序模块内的某个文件夹访问文件?

sr4lhrrt  于 2023-08-06  发布在  Android
关注(0)|答案(1)|浏览(120)

考虑一个包含3个子项目的gradle项目:

root
    |
    |> androidModule
    |> coreModule
    |> desktopModule

字符串
我决定集中一些项目文件(例如:字体,二进制文件)内的coreModule,但我不能加载,然后在androidModule。一旦这些文件在androidModuledesktopModule中使用,就会选择此选项。
我尝试了很多在androidModule/build.gradle.kts中声明自定义sourceSets的方法,但仍然无法访问这些文件。到目前为止,我尝试了一次:

android {
  sourceSets["main"].resources {
    srcDirs(arrayOf("coreModule/example/targeted/folder", "other/path", "etc"))
  }
}


此外,我尝试在一些Android活动代码中加载文件:

val resultStream = assets.open("file-from-the-custom-folder") //no such file or directory here
println(resultStream)


那么,如何处理android gradle模块中的多个资源目录呢?
我试图避免将文件集中在androidModule中,因为我认为如果生活在该模块中,其他模块可以轻松访问它们,顺便说一下,我也真的认为文件应该在核心模块中,使这个地方在位置/路径方面更加一致。处理这件事的最好办法是什么?

tzdcorbm

tzdcorbm1#

在不幸的回应“不可能使用任意目录”作为Android和/或其他Kotlin模块访问的常见文件的保持器之后,我开始研究一些关于Gradle Source Sets的可能性。
之后,我发现我们在一个模块的build.gradle.kts文件中这样做,可以让模块看起来并使用一些文件夹作为资源/资产(一般文件,而不是源代码):

android {
  //...

  // get access to configs about the "main" source set
  sourceSets.getByName("main") {
    // creates an empty directories paths holder
    val allNeededDirectories = mutableListOf<String>()

    // adds all current existing defined dirs of the gradle defaults
    allNeededDirectories.addAll(assets.srcDirs.map { it.toString() })
    
    // adds a custom and user-created directory
    allNeededDirectories += project
      .layout
      .projectDirectory
      .dir("../my_awsome_custom_directory")
      .toString()
    
    // defines the dirs list above to be the main [assets] srcDirs
    assets.setSrcDirs(allNeededDirectories)
  }
}

字符串
请注意,../前缀用于访问my_awsome_custom_directory,它位于当前gradle模块/子项目的上一级。
另外,请注意android块。这意味着外部常规文件(例如:字体、二进制文件)被视为“资产”,而“资源”是通过R类预先索引的文件。出于这个原因,在android活动中,从my_awsome_custom_directory访问名为“my_file.test”的文件,我们可以这样做:

override fun onCreate(savedInstanceState: Bundle?) {
  val resultStreamOfFile = assets.open("my_file.test")
  println(resultStreamOfFile.readText())
}


此外,当设置自定义my_awsome_custom_directory由Android不同的其他模块访问时,例如,纯JVM,非常相似:

kotlin {
  //...

  // get access to configs about the "main" source set
  sourceSets.getByName("main") {
    // creates an empty directories paths holder
    val allNeededDirectories = mutableListOf<String>()

    // adds all current existing defined dirs of the gradle defaults
    allNeededDirectories.addAll(resources.srcDirs.map { it.toString() })
    
    // adds a custom and user-created directory
    allNeededDirectories += project
      .layout
      .projectDirectory
      .dir("../my_awsome_custom_directory")
      .toString()
    
    // defines the dirs list above to be the main [resources] srcDirs
    resources.setSrcDirs(allNeededDirectories)
  }
}


不同的是,我们需要定义到resources的路径,而不是assets。这是由于assets仅由android插件提供,而kotlin("jvm")提供resources
到最后,上面的所有实验我在我的一个应用程序中做了,并且运行良好。但是,如果我解释中有一点是混乱,或者在特定场景中不能很好地工作,请随时纠正!

相关问题