You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Android drawable资源的file://格式Uri适配Firebase Storage

Android Drawable资源转file协议Uri方案(无Bitmap OOM风险)

核心思路

直接通过IO流将APK内的drawable资源拷贝到应用私有缓存目录,全程不加载Bitmap,内存占用极低,完全避免OOM问题,最终生成的缓存文件可直接输出file://开头的Uri供Firebase Storage使用。

实现代码

import android.content.Context
import android.net.Uri
import androidx.annotation.DrawableRes
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

fun getDrawableAsFileUri(context: Context, @DrawableRes drawableResId: Int): Uri {
    // 以drawable资源名作为缓存文件名,避免重复生成
    val fileName = context.resources.getResourceEntryName(drawableResId)
    val cacheFile = File(context.cacheDir, "$fileName.png")

    // 已生成过的缓存直接复用,减少IO操作
    if (!cacheFile.exists()) {
        var inputStream: InputStream? = null
        var outputStream: FileOutputStream? = null
        try {
            inputStream = context.resources.openRawResource(drawableResId)
            outputStream = FileOutputStream(cacheFile)
            val buffer = ByteArray(8 * 1024) // 8KB缓冲区,内存占用极低
            var readLength: Int
            while (inputStream.read(buffer).also { readLength = it } != -1) {
                outputStream.write(buffer, 0, readLength)
            }
            outputStream.flush()
        } finally {
            inputStream?.close()
            outputStream?.close()
        }
    }

    return Uri.fromFile(cacheFile)
}

注意事项

  • 该方案仅对png、jpg、gif等位图格式的drawable资源有效,如果是矢量图(VectorDrawable)需要先渲染成位图再写入缓存,该场景下不可避免要用到Bitmap操作,可通过控制采样率降低OOM风险
  • 缓存文件会长期存在于应用缓存目录,如果需要清理可在应用启动时统一删除缓存目录下的对应资源文件
  • 仅用于Firebase Storage上传场景时,生成的file://Uri无需额外适配Android 7.0的FileProvider规则,可直接传入Firebase Storage的上传接口使用

内容的提问来源于stack exchange,提问作者Bitwise DEVS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 16:54:05