如何使用ResourcesProvider/ResourcesLoader类动态加载资源



背景

我发现了Android 11的这些新类(ResourcesLoader和ResourcesProvider),我认为它们可以让你为整个应用程序提供自己的资源加载,这可以帮助你更喜欢来自云的字符串(如Lokalise和Crowdin)、加载主题等

问题

我找不到任何关于如何使用它们的例子,也找不到我所发现的是否正确。

我发现的关于它的唯一一件事是从这篇缓存的";驯服Android资源和布局充气器用于字符串操作":

Android 11引入了通过ResourcesLoader和ResourcesProvider。这不仅限于字符串文件,但也允许动态加载绘图和其他资源文件。这是使用这些类的近似方法

val provider = ResourcesProvider.loadFromDirectory("/somepath/", null) // or loadFromApk() 
val loader = ResourcesLoader() loader.addProvider(provider) resources.addLoaders(loader) // Application resources 

没有提供此API的正确样本现在,它只在Android 11及以上版本上可用,所以有API很长一段时间才能用于大多数应用程序。

我发现了什么

我想在Lokalise库中尝试一下,它提供了Resources的一个实例(在这里写了关于这个)。

遗憾的是,我一开始就陷入了困境,无法找到如何使用它来为它提供这个实例。

这似乎是一个罕见的用例和新类,几乎没有人愿意写它。即使是关于我从2020年发现的文章,它也被删除了,我不得不使用它的缓存版本…

问题

  1. 这些类确实可以用于动态提供资源(字符串/主题)的目的吗
  2. 它能和Lokalise一起使用吗?这样我就可以给它一个SDK的实例了
  3. 是否有这些类的支持库,以便在Android API 30之前使用

编辑:在此处找到样本。在那里,他们使用加载的APK文件,将其资源作为首要任务:

class App : Application() {
override fun onCreate() {
super.onCreate()

val file = File(cacheDir, "overrideResources")
unzip(ZipInputStream(assets.open("override.apk")), file)

val rl = ResourcesLoader()
rl.addProvider(ResourcesProvider.loadFromDirectory(file.path, null))
resources.addLoaders(rl)
}
}

如何使用ResourcesLoader/ResourceProvide?


  1. 创建编译的资源。例如,您可以使用aapt或aapt2

使用aapt的示例:

./aapt package -f -M AndroidManifest.xml -S ./res -I android.jar -F unsigned.apk

(./res文件夹必须具有结构层次结构,如./res/drawable、./res/layout等,带有资源)

aapt2示例:

./aapt2 compile "drawableyour_res_name.xml" -o "drawable"
./aapt2 link -o unsigned.apk -I "android.jar" -R "drawableyour_res_name_drawable.xml.flat" --manifest AndroidManifest.xml -v

AndroidManifest.xml应该具有相同的包名称,以便正确使用您的主应用程序。你可以在sdk文件夹中找到android.jar、aapt、aapt2文件。关于您可以阅读的所有标志->aapt-h,aapt2-h

AndroidStudio IDE

示例-构建apk的步骤:

  1. 创建一个空项目
  2. 将正确的包名称添加到AndroidManifest.xml
<manifest package="your package">

删除不必要的标签

<application android:label, android:icon, etc...>

  1. 将您的资源添加到项目中/res文件夹
  2. 清除所有不必要的资源
  3. 从build.gradle文件中删除所有依赖项
plugins {
... //your settings
}
android {
...//your settings
}
dependencies {
}
  1. 构建->构建APK

  • 之后,您获得了已编译的资源,然后:(或如何动态使用应用程序中已编译的资源)
  • File f = new File("unsigned.apk");
    ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f, MODE_READ_ONLY);
    ResourcesProvider rp = ResourcesProvider.loadFromApk(pfd);
    ResourcesLoader rl = new ResourcesLoader();
    rl.addProvider(rp);
    getResouces().addLoaders(rl);
    

    仅此而已!应用程序中的资源。您动态下载了资源。

    对于阅读资源,您可以使用:

    getResouces().getIdentifier("your_res_name", "drawable", getPackageName());
    

    是否有这些类的支持库,以便在Android API 30之前使用?

    在以前的API中不能使用ResourcesLoader。

    相关内容

    • 没有找到相关文章

    最新更新