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.png
try {
    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());
}

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

// Activity
flutterView.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 的资源文件,依旧是从零探索中;如有错误请多多指导!

来源: 阿策小和尚

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容