Flutter 59: 图解 Android Native 获取 Flutter 资源文件

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 0 基础学习 Flutter,第五十九步: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 的资源文件,依旧是从零探索中;如有错误请多多指导!

来源: 阿策小和尚

目录
相关文章
|
1月前
|
前端开发 JavaScript Android开发
Flutter 与 React Native - 详细深入对比分析(2024 年)
Flutter和React Native是两大跨平台框架,各有优缺点。Flutter性能优越,UI灵活,使用Dart;React Native生态广泛,适合JavaScript开发。
236 5
Flutter 与 React Native - 详细深入对比分析(2024 年)
|
20天前
|
移动开发 Dart 搜索推荐
打造个性化安卓应用:从零开始的Flutter之旅
【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
74 7
|
2月前
|
开发框架 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
85 15
|
2月前
|
Dart 开发工具 Android开发
在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
|
2月前
|
开发框架 Dart 前端开发
Android 跨平台方案对比之Flutter 和 React Native
本文对比了 Flutter 和 React Native 这两个跨平台移动应用开发框架。Flutter 使用 Dart 语言,提供接近原生的性能和丰富的组件库;React Native 则基于 JavaScript,具备庞大的社区支持和灵活性。两者各有优势,选择时需考虑团队技能和项目需求。
332 8
|
2月前
|
安全 Android开发 开发者
探索安卓开发的未来:Kotlin的崛起与Flutter的挑战
在移动开发的广阔天地中,安卓平台始终占据着举足轻重的地位。随着技术的不断进步和开发者需求的多样化,Kotlin和Flutter成为了改变游戏规则的新玩家。本文将深入探讨Kotlin如何以其现代化的特性赢得开发者的青睐,以及Flutter凭借跨平台的能力如何挑战传统的安卓开发模式。通过实际案例分析,我们将揭示这两种技术如何塑造未来的安卓应用开发。
73 6
|
3月前
|
搜索推荐 IDE 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
在数字时代的浪潮中,拥有一款个性化且高效的移动应用已成为许多创业者和企业的梦想。本文将引导你使用Flutter框架,从零基础开始构建一个安卓应用,不仅涉及界面设计、功能实现,还包括性能优化的关键技巧。通过简洁易懂的语言和实用的代码示例,我们将一起探索如何让你的应用在众多竞争者中脱颖而出。 【8月更文挑战第31天】
|
3月前
|
存储 开发工具 Android开发
打造你的专属安卓应用:从零开始的Flutter之旅
【8月更文挑战第31天】在数字时代的浪潮中,拥有一款属于自己的应用不仅是梦想的启航,也是技术实力的展现。本文将引导你使用Flutter框架,轻松步入安卓应用的开发世界。无论你是编程新手还是希望拓展技能边界的开发者,跟随这篇指南,你将学会如何搭建开发环境、设计用户界面,并实现基本功能。让我们一起探索代码的力量,开启一段创造之旅吧!
|
3月前
|
移动开发 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第31天】探索Flutter,一个革命性的UI工具包,它让开发者能够使用一套代码库构建美观、快速的原生应用。本篇文章将带你领略Flutter的魅力,通过实际示例揭示如何快速搭建一个安卓应用。无论你是新手还是有经验的开发者,这篇文章都将为你提供价值。