写点什么

【Flutter 专题】59 图解 Android Native 获取 Flutter 资源文件

发布于: 1 小时前
【Flutter 专题】59 图解 Android Native 获取 Flutter 资源文件

      小菜前段时间研究了 Android NativeFlutter 之间的交互;若两端均需要相同资源文件,若不能共享则势必会增加整体包大小;今天小菜研究一下如何通过 Android Native 获取 Flutter 中资源文件;



      官网对于 assets 介绍很简洁,使用过程代码量也很少,虽简洁但依然值得研究;小菜以 Android 为主工程,Flutter 作为 Module 进行测试;



FlutterView

      小菜学习 AndroidFlutter 交互时会用到 FlutterView 作为桥接控件;而对于资源文件的获取也同样适用;其核心方法是 getLookupKeyForAsset

源码分析

      逐层分析源码,通过 getLookupKeyForAsset 方法我们可以获取资源文件的路径,根目录是固定的 flutter_assets 而非 Module 名;


public String getLookupKeyForAsset(String asset) {    return FlutterMain.getLookupKeyForAsset(asset);}public static String getLookupKeyForAsset(String asset) {    return fromFlutterAssets(asset);}private static String fromFlutterAssets(String filePath) {    return sFlutterAssetsDir + File.separator + filePath;}private static String sFlutterAssetsDir = "flutter_assets";
复制代码

案例测试

      小菜通过 getLookupKeyForAsset 获取文件路径,以 images/ic_launcher.png 图片为例,借助 assetManager.open 转为流信息转为 Bitmap 进行展示;


// 文件路径:flutter_assets/images/ic_launcher.pngtry {    AssetManager assetManager = getAssets();    InputStream is = assetManager.open(flutterView.getLookupKeyForAsset("images/ic_launcher.png"));    Bitmap bitmap = BitmapFactory.decodeStream(is);    flutterIv.setImageBitmap(bitmap);} catch (Exception e) {    System.out.println("异常信息:" + e.toString());}
复制代码


      小菜测试可以用如下方式获取资源文件路径;


// ActivityflutterView.getLookupKeyForAsset("images/ic_launcher.png");// Fragment(FlutterView) getView().getLookupKeyForAsset("images/ic_launcher.png");// 通用FlutterMain.getLookupKeyForAsset("images/ic_launcher.png");
复制代码

PluginRegistry.Registrar

      另一种常用的方式是以插件方式,Flutter 在使用 AndroidView 方式嵌入 Native ViewAndroid 进行交互时;核心方法同样是 lookupKeyForAsset 获取资源路径,之后便是用原生方法解析 assets 资源文件;


      小菜测试时主要注意两点:


  1. 获取 PluginRegistry.Registrar,不能直接 new 对象,需要注册自定义 Native View

  2. 在获取文件路径后尝试了 AssetFileDescriptor 方式解析数据流,完全可以用于 assetManager.open 方式解析;


// 文件路径:flutter_assets/images/ic_launcher.png// Flutter 端Container(    child: AndroidView(        viewType: "com.ace.ace_demo01/method_layout",        creationParamsCodec: const StandardMessageCodec(),        creationParams: {'method_layout_size': 450}),    color: Colors.greenAccent,    height: 200.0)    // Android 端final String key = "NMethodLayout";if (this.hasPlugin(key)) return;PluginRegistry.Registrar registrar = this.registrarFor(key);registrar.platformViewRegistry()    .registerViewFactory("com.ace.ace_demo01/method_layout", new NMethodLayoutFactory(registrar.messenger()));
try { AssetManager assetManager = registrar.context().getAssets(); String assetKey = registrar.lookupKeyForAsset("images/ic_launcher.png"); AssetFileDescriptor fileDescriptor = assetManager.openFd(assetKey); Bitmap bitmap = BitmapFactory.decodeStream(fileDescriptor.createInputStream()); mIv.setImageBitmap(bitmap);} catch (Exception e) { e.printStackTrace();}
复制代码

注意事项

      无论是 FlutterView 还是 PluginRegistry.Registrar 方式均需 lookupKeyForAsset 获取 Flutter 端资源文件路径,且获取类型与原生 assets 中一致;小菜测试获取一个 json 文件进行解析;


final String key = "NMethodLayout";if (this.hasPlugin(key)) return;PluginRegistry.Registrar registrar = this.registrarFor(key);registrar.platformViewRegistry()    .registerViewFactory("com.ace.ace_demo01/method_layout", new NMethodLayoutFactory(registrar.messenger()));
try { AssetManager assetManager = registrar.context().getAssets(); Log.e("===getJson===", getJson(registrar.lookupKeyForAsset("images/star.json")));} catch (Exception e) { e.printStackTrace();}
public String getJson(String fileName) { StringBuilder stringBuilder = new StringBuilder(); try { //获取assets资源管理器 AssetManager assetManager = getAssets(); //通过管理器打开文件并读取 InputStreamReader inputReader = new InputStreamReader( assetManager.open(fileName) ); BufferedReader bufReader = new BufferedReader(inputReader); String line="", result=""; while((line = bufReader.readLine()) != null) result += line; return result; } catch (IOException e) { e.printStackTrace(); } return stringBuilder.toString();}// ===getJson===: { "stars": [ { "name": "水瓶座", "name_en": "Aquarius" }, { "name": "双鱼座", "name_en": "Pisces" }, { "name": "白羊座", "name_en": "Aries" }, { "name": "金牛座", "name_en": "Taurus" }, { "name": "双子座", "name_en": "Gemini" }, { "name": "巨蟹座", "name_en": "Cancer" }, { "name": "狮子座", "name_en": "Leo" }, { "name": "处女座", "name_en": "Virgo" }, { "name": "天秤座", "name_en": "Libra" }, { "name": "天蝎座", "name_en": "Scorpio" }, { "name": "射手座", "name_en": "Sagittarius" }, { "name": "摩羯座", "name_en": "Capricorn" } ]}
复制代码




      小菜还未成功尝试 Flutter 获取 Native 的资源文件,依旧是从零探索中;如有错误请多多指导!


来源: 阿策小和尚

发布于: 1 小时前阅读数: 3
用户头像

还未添加个人签名 2021.05.13 加入

Android / Flutter 小菜鸟~

评论

发布
暂无评论
【Flutter 专题】59 图解 Android Native 获取 Flutter 资源文件