访问包内主应用程序的资产

Posted

技术标签:

【中文标题】访问包内主应用程序的资产【英文标题】:Accessing assets of main application inside package 【发布时间】:2022-01-17 20:42:27 【问题描述】:

我目前正在尝试使用 Kotlin 为 Flutter App 开发一个包。我的问题是我需要为包提供一个配置文件,该文件只能在主应用程序中定义。由于 Dev 和 Prod 环境的配置不同,应用程序应该通过方法通道传递文件的路径。问题是包无法访问调用应用程序的资产文件夹。 路径:"assets/config.json"(根为主应用)

我已经尝试过的步骤:

    在 res/raw 中创建文件并通过 ressource id 访问配置文件 -> Kotlin 给我一个“未解决的引用”错误,除非我在包 res/raw 中创建文件

    我没有通过路径,而是尝试通过配置的内容并将其写入一个空的临时文件。 Kotlin 中的代码是这样的:

        val config = File(applicationContext.filesDir,"config.json")
        config.writeText(configContent)
    

-> 这行得通,但它似乎是一个奇怪的问题解决方案。

如果我需要提供更多信息,请告诉我并提前感谢您!

编辑:

初始化期间调用的Java方法:

public static void createMultipleAccountPublicClientApplication(@NonNull final Context context,
                                                                @NonNull final File configFile,
                                                                @NonNull final IMultipleAccountApplicationCreatedListener listener)

【问题讨论】:

如您所见,您需要将资产写入某个文件中的某个位置(如果它确实必须是一个文件)。您可以按照您显示的方式进行操作,或者让 Dart 将其写入您创建的临时文件,例如 path_provider,然后通过通道传递文件名。这确实提出了为什么你的插件需要一个文件的问题。例如,它不能从内存中的字符串解析其配置吗? 感谢您的回答!我基于此插件的库需要在初始化期间从文件中解析配置。 (我将添加一个示例作为编辑)应用程序应该在哪里创建此文件,以便插件可以访问它?是否有与我在 Dart 示例中显示的 filesDir 的等价物? 【参考方案1】:

Flutter 资产不是文件——它们被打包并且只能通过rootBundle 获得。因此,如果您想从文本资源创建文件,则必须有人加载资源并将其写入文件。

由于您的插件用户将负责资产,因此他们必须执行第一部分(最终会得到 String)。问题是由谁来写。

您可以让插件用户使用path_provider 找到临时目录并将其写入那里,然后将文件路径传递给您。最终,在 Java 中,你 new File(theTempFilePath)。或者他们可以将字符串传递给插件的 Dart 部分,然后您以相同的方式创建临时文件。

如果他们将字符串传递给您的插件可能会更方便,您将其传递给本机端并让本机端创建一个临时文件并将字符串写入那里。 (顺便说一句,我假设我们正在谈论这个配置文件:https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-configuration#how-to-use-a-configuration-file)

查看创建临时文件的答案:Creating temporary files in android

请注意,您的插件用户实际上没有理由需要使用资产。相反,如果配置从未真正改变,他们可以直接在代码中硬编码字符串。

有一个论点是,由于这是一个 JSON 配置文件,您可能不想用这个 JSON 配置文件的详细信息来打扰您的用户。你可能想在你的 Dart 代码中默认它(为什么不把它硬编码为一个字符串,如上所述,如果它从未真正改变过),然后提供一些方法来覆盖特定值,如客户端 id 和重定向 uri,这可能是用户在实践中唯一改变的东西。因此,与其让他们提供一个完整的 JSON 文件,他们只是给你这两个字符串,然后你将它们放入默认的 JSON 中。也许是第 2 版的功能:)

【讨论】:

我想知道你是否会发现在 Dart 中简单地实现你需要的 MSAL 库的部分会更容易。为什么要努力制作一个插件来包装 Android 和 ios 实现——它们是开源的,你可以阅读它们是如何工作的。如果您只需要身份验证,请查看pub.dev/packages/openid_client。我们为 Azure 编写了自己的 OpenID 连接客户端,所以完全有可能。 哇,非常感谢您的详细解释!我很好奇如果 MSAL 库中有更改,您将如何更新您的实现?还是身份验证方法不是定期更新的?首先,我不能声称通过 Kotlin 包装它是我的想法,因为我只是更新了一个过时的包。但是,如果要获得最新的安全功能,只需更改 gradle 中的版本号,它似乎更易于维护,不是吗? :) 我认为 OpenID Connect 规范的变化不会那么快。

以上是关于访问包内主应用程序的资产的主要内容,如果未能解决你的问题,请参考以下文章

如何在 watchOS 应用程序的共享框架中访问资产目录中的颜色?

从monodroid类库中访问资产

Angular 5:如何访问应用程序或资产文件夹之外的图像文件?

无法加载资产颤振(不是资产是保存的文件)

部署在 github.pages 上的 Flutter Web 应用程序无法访问某些资产

java中的public,protected,private权限修饰