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

Android Kotlin Firebase:获取两张图片入Bitmap数组遇越界错误求助

问题分析

你遇到的IndexOutOfBoundsException核心原因是Firebase Storage的文件下载是异步操作:你在代码中直接执行bitmapArray.addAll()、shuffle()以及按钮绑定逻辑时,两张图片还没完成下载,此时bitmapArray是空的,访问bitmapArray[index]自然会触发数组越界异常。另外原代码中bitmapArray.addAll(bitmapArray)的写法逻辑错误,空数组执行该操作后依然为空。

解决方案

1. 核心修正思路

等待两张图片的异步下载任务全部完成后,再执行数组复制、打乱和按钮绑定操作,可借助Firebase的Tasks.whenAll()API监听多个异步任务的完成状态。

2. 修改后的完整代码

val aDatabase = FirebaseStorage.getInstance().getReference("all/$imageID1.jpg")
val sDatabase = FirebaseStorage.getInstance().getReference("all/$imageID2.jpg")

val bitmapArray = mutableListOf<Bitmap>()

// 创建第一个图片的下载任务
val downloadTask1 = try {
    val localFile = File.createTempFile("tempfile", ".jpg")
    aDatabase.getFile(localFile).addOnSuccessListener {
        val bitmap = BitmapFactory.decodeFile(localFile.absolutePath)
        bitmapArray.add(bitmap)
    }.addOnFailureListener {
        Log.w("myapplication", "ERROR RETRIEVING IMAGE 1")
        Toast.makeText(this, "ERROR RETRIEVING IMAGE 1", Toast.LENGTH_SHORT).show()
    }
} catch (e: Exception) {
    e.printStackTrace()
    null
}

// 创建第二个图片的下载任务
val downloadTask2 = try {
    val localFile = File.createTempFile("tempfile1", ".jpg")
    sDatabase.getFile(localFile).addOnSuccessListener {
        val bitmap = BitmapFactory.decodeFile(localFile.absolutePath)
        bitmapArray.add(bitmap)
    }.addOnFailureListener {
        Log.w("myapplication", "ERROR RETRIEVING IMAGE 2")
        Toast.makeText(this, "ERROR RETRIEVING IMAGE 2", Toast.LENGTH_SHORT).show()
    }
} catch (e: Exception) {
    e.printStackTrace()
    null
}

// 等待两个下载任务全部完成后再执行后续逻辑
if (downloadTask1 != null && downloadTask2 != null) {
    Tasks.whenAll(downloadTask1, downloadTask2).addOnCompleteListener { task ->
        if (task.isSuccessful && bitmapArray.size == 2) {
            // 生成包含重复元素的数组(每个图片各两张,满足2×2配对需求)
            val cardList = mutableListOf<Bitmap>().apply {
                addAll(bitmapArray)
                addAll(bitmapArray)
            }
            cardList.shuffle()

            // 绑定按钮与点击事件
            val button1 = findViewById<ImageButton>(R.id.imageButton1)
            val button2 = findViewById<ImageButton>(R.id.imageButton2)
            val button3 = findViewById<ImageButton>(R.id.imageButton3)
            val button4 = findViewById<ImageButton>(R.id.imageButton4)
            val buttons = listOf(button1, button2, button3, button4)

            buttons.forEachIndexed { index, button ->
                button.setOnClickListener {
                    button.setImageBitmap(cardList[index])
                }
            }
        } else {
            Log.w("myapplication", "One or both image downloads failed")
            Toast.makeText(this, "Failed to load images", Toast.LENGTH_SHORT).show()
        }
    }
}

关键说明

  • 用Tasks.whenAll()确保只有两张图片都成功下载后,才处理数组和按钮逻辑,从根源避免空数组访问。
  • 单独创建cardList存放重复元素,保证最终数组有4个元素,符合2×2卡片配对的需求。
  • 增加bitmapArray.size == 2的判断,避免单张图片下载失败导致的元素不足问题。

内容的提问来源于stack exchange,提问作者Berk Sunduri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:21:00