用 Golang 开发 Android 应用(三)—— Storage(Asset) 使用

Unity游戏集成Android文件管理器:从Intent调用到Uri处理的完整指南 在移动应用开发中,跨平台交互与本地系统功能集成是常见的工程需求,其核心在于理解不同运行环境间的通信机制。Unity引擎开发的游戏运行在C#/.NET环境,而Android系统基于Java/Kotlin,两者间的交互通常通过JNI(Java Native Interface)或Android原生API桥接实现。这种技术方案的价值在于能直接调用系统级服务,如文件管理、相机、传感器等,从而突破引擎沙盒限制,丰富应用功能。具体到文件访问场景,Android的Activity与Intent机制提供了标准的系统级交互范 阅读详情

计划按以下的内容更新

Storage 使用

关于 Asset

所谓 Storage 是在 Android 里除了正常文件系统之外,它还实现了两种特殊的“文件存储”方式,一种是 OBB 另一种是 Asset, OBB 是独立于 APK 之外的资源包,而 Asset 是 APK 内置的文件。OBB 使用较少,所以 OBB 就跳过不提,只说明一下 Asset 用法。
我们解开一些 APK 可能会发现它里面有一个 assets 目录(解不开?改扩展名为.zip)。典型的如:

│  AndroidManifest.xml
│  classes.dex
│  resources.arsc
│
├─assets
│   ...
├─lib
│   ...
├─META-INF
└─res
    ...

这个目录是在 APK 内部,显然它和 APK 是一起发布的。关于它的使用场景,用一个词典应用来说,基础的词库可以放在 assets 这个目录(内置词库),而如果是要付费的一些专业词库则可以通过网络下载到手机,用正常文件系统来访问。在我们用 Golang 开发应用的情况下,它也可以用来放应用的界面资源,如图标、字串、界面布局等等。可参考示例文件。

Assets 相关对象

在应用中如何访问这个目录?
相关的对象有:

  • AssetManager
  • AssetDir
  • Asset
AssetManager 说明

它是通过调用 func (a *Activity) AssetManager() *AssetManager 得到的。
并且它只有两个函数


// Open the named directory within the asset hierarchy.  The directory can then
// be inspected with the AAssetDir functions.  To open the top-level directory,
// pass in "" as the dirName.
//
// The object returned here should be freed by calling AAssetDir_close().
func (mgr *AssetManager) OpenDir(dirName string) *AssetDir 

// Open an asset.
//
// The object returned here should be freed by calling AAsset_close().
func (mgr *AssetManager) Open(filename string, mode int) *Asset 

OpenDir 是打开 assets 下的一个目录, 要注意的是根目录是用 “” 表示, 同时这也是 assets 里文件路径的表示方式,比如 asserts/a.txt 和 assets/a/b/c.txt 在调用 Open 时,filename 分别是 “a.txt” 和 “a/b/c.txt” 。
OpenDir 会返回 AssetDir 对象,下面会详细说明。

而 Open 是返回 Asset 对象,关于 Asset 就简单了,因为它是(实现了) io.ReadSeeker 和 io.Closer,也就是几乎可当它是一个 os.File 来用。注意要调用 Close 释放资源。

AssetDir 说明
// Iterate over the files in an asset directory.  A "" string is returned
// when all the file names have been returned.
//
// The string returned here is owned by the AssetDir implementation and is not
// guaranteed to remain valid if any other calls are made on this AAssetDir
// instance.
func (assetDir *AssetDir) GetNextFileName() string 

// Reset the iteration state of AAssetDir_getNextFileName() to the beginning.
func (assetDir *AssetDir) Rewind()

// Close an opened AAssetDir, freeing any related resources.
//
//void AAssetDir_close(AAssetDir* assetDir);
func (assetDir *AssetDir) Close() 

GetNextFileName 返回下一个文件名,如果返回"", 说明所有文件列举完了。请注意这里只会返回此目录下的文件,不会返回目录,不知是出于什么考虑?但对于内置文件来说,也算是合理的,理论上 APK 一发布,内置文件就是固定了的。所以从另一面来说,它是给了我们一点灵活性。

Rewind 是重置 GetNextFileName 相关状态和指针,使 GetNextFileName 又从第一个文件开始列举。

示例代码

列举目录下所有文件的代码如下:

func AssetInfo(act *app.Activity, dir string) {
	assetMgr := act.AssetManager()
	assetDir := assetMgr.OpenDir(dir)
	defer assetDir.Close()

	assetDir.Rewind() 
	for {
		// 得到下一个文件名,但不能列出子目录
		fname := assetDir.GetNextFileName()
		if fname == "" {
			return
		}
		...
		
	}
}

请参考示例,这个例子中 assets 目录树如下:

│  AndroidManifest.xml
│
├─assets
│  │  label_icon.png
│  │  readme_root.txt
│  │
│  └─a
│          readme_a.txt

因为无法列出子目录,因此对于本例的目录树,对于 assets 需调用 AssetInfo(acr, "") ,对于 assets/a 需调用 AssetInfo(act, "a") 。

关于 ReadImage

示例中有个 ReadImage 函数,既说明了 Asset 文件的用法,同时这个例子也演示了 imgui 中图像的显示。
在这里插入图片描述

主要是三步:

  1. 图像解码
  2. 生成 OpenGL texture
  3. 调用 imgui.Image
func ReadImage(act *app.Activity, fname string) image.Image {
	// load image
	m := act.AssetManager()
	fa := m.Open(fname, storage.ASSET_MODE_BUFFER)
	buf := make([]byte, fa.Length())
	fa.Read(buf)

	img, _, err := image.Decode(bytes.NewBuffer(buf))
	if err != nil {
		log.Println("ReadImage:", err)
	}
	fa.Close()

	// 转换成 RGBA 格式
	dst := image.NewRGBA(img.Bounds())
	imagedraw.Draw(dst, dst.Bounds(), img, image.Point{}, imagedraw.Src)
	return dst
}

需要注意的是上面例子中有个 “转换成 RGBA 格式” 的操作,这个效率非常低,不建议这么做,要尽量避免数据转换。如果是 openGL 支持的格式如 RGB565 等,根据不同的图像数据格式找到对应参数直接生成 texture ,如果是不支持的数据格式则可用 GLSL 来绘制。

Assets 总结

上面已经说过 assets 目录下可以用来放应用的界面资源,如图标、字串、界面布局等等。然后是应用需要的数据,这里需要再次提醒的是因为不能列举目录,所以在目录设计的时候需要考虑这个因素,如果做成数据驱动的方式则需要把目录定下来,而以文件的变化作为区别。比如说惯用的版本区分 lite 和 pro 版,它们最好保持一致的目录结构,以文件的不同来区分版本 。

Unity Android相册图片加载:解决content:// URI转换与原生插件集成 在移动应用开发中,跨平台引擎与原生系统间的数据交互是常见的技术挑战,尤其是在处理设备本地资源时。Android系统基于安全模型,使用content:// URI机制抽象化文件访问,但这与Unity引擎直接的文件路径读取方式存在兼容鸿沟。其技术原理在于Android的Content Provider架构,它通过统一资源标识符封装数据源,要求通过ContentResolver进行流式访问。这一机制的技术价值在于保障用户数据安全与应用沙箱隔离,但给Unity开发者带来了图片加载的实践难题。应用场景广泛涉及用户头像 阅读详情

相关推荐

Unity游戏开发:SQLite4Unity3d插件集成与数据存储实战指南

在游戏与应用开发中,本地数据存储是构建稳定、高效应用的基础技术之一。其核心原理是通过轻量级数据库引擎,在客户端设备上实现结构化数据的持久化存储,避免了依赖网络和复杂服务器配置。这项技术的核心价值在于为单机应用、移动端游戏和编辑器工具提供了即插即用的数据管理能力,极大提升了开发效率和用户体验。在Unity开发领域,本地数据存储的典型应用场景包括玩家存档管理、游戏配置读取、装备系统与对话树等复杂游戏逻辑的数据支撑。本文聚焦于Unity环境下最成熟的本地存储解决方案之一——SQLite4Unity3d插件,深入解

weixin_30588675的博客 319

用 Golang 开发 Android 应用(非 gomobile)(一 )—— 基本环境配置

用 Golang 开发 Android 应用 -- 基本环境配置——题记计划按以下的内容更新基本环境配置Golang 和 android 有什么关系?基本 go 编译环境Android 的 ndk 编译器的配置命令行环境设置和编译其它 ——题记 遭遇经济寒冬加上中年危机(看我在优快云的注册时间,就知道本人有多“少年”了_),所以简历看得人多,有兴趣聊聊的人少。有人会说是没转到管理的原因,哥可是1...

kaisoft的专栏 3万+

Unity游戏开发实战:SQLite数据库集成与优化指南

在游戏开发中,数据持久化是构建复杂游戏系统的核心技术之一。关系型数据库通过结构化查询语言(SQL)提供了强大的数据管理能力,其核心原理在于使用表、行、列的结构化方式存储数据,并通过事务、索引等机制保证数据的一致性与查询效率。对于需要本地存储玩家进度、道具库存和配置数据的单机或移动端游戏,嵌入式数据库的技术价值尤为突出,它无需独立服务器,可直接集成在应用内。SQLite作为轻量级、零配置的嵌入式关系型数据库,完美契合Unity游戏的跨平台部署需求,能够有效替代PlayerPrefs和JSON文件,解决复杂数据

weixin_30385925的博客 304

GameFramwork学习(五):资源管理(Resource)上篇

本文分析了GameFramework中的资源管理机制。

qq_44195770的博客 395

Unity视频播放进阶:AVProVideo插件在UI与3D渲染中的实战应用

在Unity开发中,视频播放是构建丰富多媒体体验的核心技术之一。其原理涉及解码、渲染管线集成与资源管理等多个层面。从技术价值看,高效的视频播放能力能显著提升应用的视觉表现力与用户沉浸感,广泛应用于游戏过场、交互式UI、虚拟现实及数字孪生等场景。针对Unity原生VideoPlayer组件在性能、兼容性与高级功能上的局限,开发者常寻求更强大的第三方解决方案。本文聚焦于AVProVideo这一专业插件,深入探讨其如何通过底层优化解决UI Canvas上的高性能播放与3D物体动态纹理映射两大核心痛点,并结合对象池

weixin_33719619的博客 388

量化数据采集实战:从App接口逆向到Python爬虫系统构建

数据采集是量化分析和自动化策略的基石,其核心原理是通过程序模拟客户端行为,从目标服务器获取结构化数据。在金融科技领域,高效、稳定的数据采集能力直接决定了策略研究的深度和时效性。面对金融App常见的反爬机制,如请求签名和身份认证,工程师需要掌握网络协议分析、接口逆向与模拟请求等关键技术。这些技术不仅能用于获取市场情绪、资金流向等高频数据,更是构建个人量化研究基础设施、实现从主观看盘到客观数据分析转型的关键一步。本文以实战为例,深入剖析了如何系统性地逆向分析数据接口、破解签名算法,并最终构建一个包含代理IP池与

weixin_29032489的博客 1479

go语言android开发环境搭建,golang开发android应用(一) - go语言android应用环境搭建...

基于golang的android动态库开发,很久以前golang就支持开发android上的动态库及应用了,golang的环境搭建就不说了,直接从gomobile开始软件依赖golang, gomobile, jdk,android sdkgomobilegomobile就是一个可以利用golang来开发android上本地应用及动态库的一个golang框架,我们通过他能生成能在android程序...

weixin_42545163的博客 2716

大模型越狱指令数据集全解析:从AdvBench到HarmBench

本文全面解析了AdvBench、HarmBench等主流大模型越狱指令数据集。AdvBench作为基础测试集,用于快速评估模型安全基线;HarmBench则以其全面的文本、多模态及对抗性攻击评估,成为当前权威的深度安全审计工具。文章还介绍了MaliciousInstruct、JailbreakBench等特色数据集,并提供了根据实际场景选择与使用这些数据集的具体实战指南。

weixin_29327525的博客 617

Openharmony 实战:Flutter前言及环境配置+第三方库介绍

(注:建议勾选“添加到PATH(需要重启)”;如果HarmonyOS toolchain报错的话,可以尝试在DevEco里面先建一个项目,这样ohpm就会自动下载了,node我是在node的官网上下载安装的。(注:如果安装过程中你勾选了更新PATH变量,需要重启电脑才可以生效):直接编译为原生ARM代码,渲染使用自研Skia引擎,性能接近原生。:一套代码可运行在多个平台(移动、Web、桌面、嵌入式)。我是在GIT BASH上面进行的操作,在cmd上也可以的。:基于Widget的声明式UI,状态管理高效。

Helen_cai的博客 836

STM32N6:MCU+NPU架构如何重塑边缘AI部署新范式

STM32N6作为业界首款MCU+NPU架构的通用微控制器,通过集成600 GOPS算力的NPU与800MHz Cortex-M55内核,实现了边缘AI部署的革命性突破。该方案在工业视觉和智能家居等场景中,以超低功耗和成本提供实时AI处理能力,性能较传统MCU提升超100倍,重塑了边缘智能设备的设计范式。

g8f9d0s1a2的博客 1291

数字电路基础(CMOS电路、低功耗方法)

文章目录一、CMOS器件1.1.CMOS反相器1.2. CMOS与非门1.3.CMOS或非门1.4 CMOS与门和CMOS或门二、CMOS电路参数——功耗 一、CMOS器件 1.1.CMOS反相器 CMOS反相器实现非门功能,由一个PMOS管和一个NMOS管组成,其逻辑电路图如下: 其真值表如下: In PMOS NMOS Out 0 √ 导通 ×关闭 1 1 ×关闭 √...

Mr.翟的博客 1万+

Unity独立应用文件浏览器开发指南:跨平台原生对话框集成与自定义UI实现

在桌面应用开发中,文件系统交互是基础且关键的功能模块,其核心在于提供稳定、原生的用户体验。跨平台文件对话框通过封装不同操作系统的原生API(如Windows的GetOpenFileName、macOS的NSOpenPanel),实现了统一的调用接口,解决了运行时环境下的文件选择难题。这一技术对于提升工具软件、内容创作平台等独立应用的专业度至关重要。在Unity引擎中,StandaloneFileBrowser插件正是这一原理的工程实践,它作为桥梁,将复杂的平台差异封装为简洁的C#接口。开发者借此可快速实现文

agcozdwdfvds08078的博客 453

双三相电机控制避坑指南:为什么你的SVPWM谐波大?四矢量调制实战解析

本文深入解析双三相电机控制中SVPWM谐波大的问题,并提供四矢量调制实战方案。通过分析谐波来源、四矢量调制原理及工程实现步骤,显著降低电流THD至3-5%,提升系统效率2.3个百分点。特别适合需要优化电机控制的工程师参考。

weixin_30645617的博客 397

思源笔记:块级知识工作空间的架构剖析、Docker 部署与 CLI 实战指南

思源笔记(SiYuan)是一款隐私优先、可自托管的个人知识管理系统,以细粒度块(Block)级引用和 Markdown 所见即所得编辑为核心卖点。本文基于项目仓库中的 [中文 README](https://link.gitcode.com/i/b609bd455658afbbb2ff57dace713924) 展开,系统梳理其核心特性、架构与生态,并完整给出 Docker、Unraid、True

gitblog_00542的博客 550

fasterlio原理及代码框架梳理

Faster-LIO 的优势是在保持同等高精度的前提下,显著提升计算效率,以支持更极端的应用场景(如高速无人机)和更廉价的硬件平台。可以把 Faster-LIO 理解为用一把更快的“空间哈希筛子”(iVox)替换了原来精细的“动态平衡树”(ikd-Tree),从而在精度损失极小的情况下,实现了效率的显著提升。:只在实际有地图点的空间区域动态创建和保留体素单元,形成一个稀疏的体素地图。是关键:将去畸变点云中的每个点,在 iVox 维护的局部地图中搜索近邻(如5个最近点),构建点到面的距离残差。

Studying…… 246

webview_flutter_android 全解析:从 2.0.13 到 3.3.0 的架构演进与核心能力实战指南

`webview_flutter_android` 是 Flutter 官方维护的 `webview_flutter` 联邦插件(federated plugin)中的 Android 平台实现,负责在 Android 端将系统 `android.webkit.WebView` 的能力桥接到 Flutter 应用。本文以该包的 [CHANGELOG.md](https://link.gitcode

gitblog_00112的博客 301

【安全启动】HSM安全启动原理与技术实现白皮书

摘要: 安全启动(Secure Boot)与度量启动(Measured Boot)通过硬件信任根(HSM/TPM等)确保系统启动链路的可信性,实现代码验证与状态记录。HSM作为核心组件,承担密钥保护、签名验证和密码运算任务,与SHE、TPM等协同构建分层信任链。通用计算与嵌入式/汽车场景的启动流程差异显著,前者依赖TPM的PCR度量,后者以HSM为核心实现硬件级安全闭环。工程实践中需权衡性能、合规性及抗攻击能力,并结合后量子密码(PQC)等演进技术优化方案。

weixin_46481662的博客 831

Unity AssetBundle原生加载机制深度解析

AssetBundle是Unity运行时资源动态加载的核心机制,本质并非压缩包,而是序列化后的二进制资源图谱,包含Header、AssetTable和Data Block三层结构。其加载性能瓶颈主要在Stage 4——平台相关的GPU解码阶段(如ASTC/ETC2纹理解压、Shader Variant链接),而非磁盘IO或网络传输。该机制深度耦合Build Target、IL2CPP元数据、Shader裁剪与Native Plugin路径,导致跨平台加载失败、黑屏、内存泄漏等典型问题。理解AssetBund

weixin_34168880的博客 525

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Google Agent Skills 完全指南:安装、组织与使用 136 个官方 Google Cloud Agent Skills 及其插件

本文以官方 skills 仓库的 README 为主线,系统讲解这个 Google 产品 Agent Skills 集合库的定位、目录组织、两种安装通道(`npx skills` 与各 Agent harness 插件市场)、12 大类 136 个技能的完整目录,以及基于 [index.json](https://link.gitcode.com/i/16635ff66b2b183f5b4996a

gitblog_00069的博客 179

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

SiYuan 开源知识工作空间完全指南:架构、自托管部署与内核 CLI 实战

SiYuan(思源笔记)是一个隐私优先、自托管的个人知识管理(PKM)系统,核心能力是块(Block)级引用与双向链接、Markdown WYSIWYG 编辑,以及让本地文件目录本身就成为数据事实来源的存储设计。本文基于仓库中的官方说明文档 [README.ja.md](https://link.gitcode.com/i/a8510273db34f9da27e76ab7a0e32a49) 整理并

gitblog_00292的博客 504

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

SiYuan 自托管知识工作空间:从架构、Docker 部署到内置 CLI 的完整实践指南

Siyuan 是一个隐私优先、完全开源、可自托管的个人知识管理工作空间,支持块级(Block)引用与双向链接、Markdown WYSIWYG 所见即所得编辑。本篇以仓库 README 为核心骨架,结合内核源码逐层展开:先讲清 Siyuan 的定位与功能边界,再给出 Docker 自托管部署的完整参数与排错要点,最后深入内置命令行工具(CLI)与数据工作空间的结构,读完后你可以独立完成服务端部署、

gitblog_00721的博客 588

Expo FileSystem 现代文件系统 API 演进全解析:File/Directory 类式接口、FileHandle 与网络任务实战

`expo-file-system` 是 Expo 生态中面向 Android、iOS 与 Web 的本地文件系统模块,负责文件的读写、复制移动、下载上传、目录遍历与系统文件选择器集成。本文以 [packages/expo-file-system/CHANGELOG.md](https://link.gitcode.com/i/ac4035dc4c799e4f54575fcaf7a55020) 为

gitblog_00161的博客 645

长任务编排系统选型指南:Airflow、Prefect、Dagster与Temporal深度对比

长任务编排是现代数据与业务系统的核心能力,指对持续数小时乃至数天、依赖复杂、状态需精确追踪且支持人工干预的流程进行可靠调度与治理。其技术本质涉及状态持久化、事件驱动、数据契约与分布式事务一致性等关键原理,直接决定系统的稳定性、可观测性与运维韧性。在ETL流水线、AI训练作业、跨微服务订单履约、金融对账等典型场景中,不同编排框架展现出显著差异:Airflow擅长确定性批处理,Prefect强化开发者对任务生命周期的显式控制,Dagster以数据资产为中心构建可信闭环,Temporal则通过可重放工作流原生支撑

weixin_34414196的博客 254
上一篇: 用 Golang 开发 Android 应用(二)—— 简单 UI
下一篇: 用 Golang 开发 Android 应用(四)—— Sensor 使用
kaisoft
博客等级 码龄26年 39粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值