【问题标题】:Is there a way to access Flutter resources from native code?有没有办法从原生代码访问 Flutter 资源?
【发布时间】:2019-10-13 19:55:57
【问题描述】:

我想在我的原生 Android 代码中使用来自 Flutter 资源的主徽标——例如,显示通知。如您所知,在 Android 中,您通常会从 drawable 文件夹中获取资源,例如 R.drawable.icon。但随后我也必须将图标复制到 Android 可绘制文件夹。也许有一种方法可以从原生代码访问 Flutter 资源(读取 - 资产)?

【问题讨论】:

  • 试图analyze .apkflutter run / flutter build 工具创建的文件?您是否注意到它在根目录中包含 assets 文件夹?

标签: android flutter


【解决方案1】:

flutter documentation 中有一个很好的部分。

给定一个资产“icons/heart.png”,适用于 android(自 1.22 起):

FlutterLoader 加载器 = FlutterInjector.instance().flutterLoader();

String key = loader.getLookupKeyForAsset("icons/heart.png");

对于 iOS (swift):

let key = registrar.lookupKey(forAsset: "icons/heart.png");

让 path = Bundle.main.path(forResource: key, ofType: nil)

对于 iOS (obj-c):

NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];

NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];

对于 Flutter 1.22 版之前的 android(已弃用):

AssetManagerassetManager = registrar.context().getAssets();

String key = registrar.lookupKeyForAsset("icons/heart.png");

AssetFileDescriptor fd = assetManager.openFd(key);

但是,您将无法直接将可绘制项目共享给 Flutter,而且主图标有点特殊,您也绝对不能与 Flutter 共享。 Flutter 不知道什么是“drawable”,而是以自己的跨平台方式处理资源。

【讨论】:

  • 如果我不在插件上而是在 MainActivity 中怎么办? stackoverflow.com/questions/65374762/…
  • 您如何将 AssetFileDescriptor 转换为 Drawable 或资源?
  • PluginRegistry.Registrar 已弃用。 @SurajNair 的回答包含更新的代码。
【解决方案2】:

新版本更新

对于 Flutter 1.22 或更高版本,FlutterLoader 只能通过 FlutterInjector 访问。

import io.flutter.FlutterInjector;

 FlutterLoader loader = FlutterInjector.instance().flutterLoader();
 String key = loader.getLookupKeyForAsset("assets_file_name");

【讨论】:

  • 然后,如何把你的钥匙变成一个 Drawable?
【解决方案3】:

您需要获取资产文件的相对路径。

以下是从 swift native 代码访问文件/图像路径的辅助方法。

func flutterAssetLottieFilePath(imageName : String) -> String {
        var flutterViewController = FlutterViewController()
        flutterViewController = UIWindow.init(frame: UIScreen.main.bounds).rootViewController as! FlutterViewController
        let key = flutterViewController.lookupKey(forAsset:"assets/images/\(imageName).png")
        let path = Bundle.main.path(forResource: key, ofType: nil)
        return path ?? ""
    }

【讨论】:

    【解决方案4】:

    截至我写这篇文章时,documentation 已经过时了。在我的颤振版本中,1.17.1 这是一个 kotlin android 示例,上面有必要的导入:

    import android.content.Context
    import io.flutter.embedding.engine.loader.FlutterLoader
    import java.io.InputStream
    
    val myAssetPath : Sting = "assets/my_asset"
    val assetLookupKey =  FlutterLoader.getInstance().getLookupKeyForAsset(myAssetPath)
    val inputStream: InputStream = applicationContext.assets.open(assetLookupKey)
    
    // Read in the file from the InputStream... 
    

    需要注意的是,从这个getLookupKeyForAsset方法返回的值通常是你的资产路径,包含在你的资产下的pubspec.yaml中,只是前缀为“颤振资产/”。所以在上面的例子中,它会返回 flutter_assets/assets/my_asset

    【讨论】:

      猜你喜欢
      • 2021-05-29
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      • 2012-06-03
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      相关资源
      最近更新 更多