从照片文件夹加载多张图像会导致内存不足异常

问题描述 投票:0回答:1

我有一个小应用程序,其中包含一个处理图片的网站。我无法从手机上传超过 5 张图片,应用程序崩溃并出现错误:
java.lang.OutOfMemoryError:无法分配 xxxxx 字节分配。

如何优化内存管理?我将非常感谢任何建议。

用户选择图像

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)if (requestCode == PICK_IMAGE_REQUEST_CODE && resultCode == RESULT_OK) {
        val selectedImageBlobs = mutableListOf<Triple<String, String, String>>()

        if (data?.clipData != null) {
            val clipData = data.clipData
            for (i in 0 until clipData!!.itemCount) {
                val uri = clipData.getItemAt(i).uri
                val base64Image = convertUriToBase64(uri)
                val mimeType = contentResolver.getType(uri)
                val fileName = getFileNameWithExtension(uri)
                if (base64Image != null && mimeType != null && fileName.isNotEmpty()) {
                    selectedImageBlobs.add(Triple(base64Image, mimeType, fileName))
                }
            }
        } else {
            val uri = data?.data
            if (uri != null) {
                val base64Image = convertUriToBase64(uri)
                val mimeType = contentResolver.getType(uri)
                val fileName = getFileNameWithExtension(uri)
                if (base64Image != null && mimeType != null && fileName.isNotEmpty()) {
                    selectedImageBlobs.add(Triple(base64Image, mimeType, fileName))
                }
            }
        }

        // Send selected image blobs, MIME types, and filenames to JSBridge
        jsBridge.sendImagePaths(selectedImageBlobs)
    }
}

此函数从设备存储中读取图像数据,转换为 Base64 字符串并返回(消耗大量内存



 private fun convertUriToBase64(uri: Uri): String? {
        return try {
            val inputStream: InputStream? = contentResolver.openInputStream(uri)
            val byteArrayOutputStream = ByteArrayOutputStream()
            val buffer = ByteArray(1024)
            var bytesRead: Int

            while (inputStream!!.read(buffer).also { bytesRead = it } != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead)
            }

            val byteArray = byteArrayOutputStream.toByteArray()
            Base64.encodeToString(byteArray, Base64.DEFAULT)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

然后我发送数据:


    private inner class JSBridge(val context: Context, private val webView: WebView) {
        fun sendData(imageFiles: List<Triple<String, String, String>>) {
            val jsonArray = JSONArray()

            for (imageFile in imageFiles) {
                val jsonObject = JSONObject()
                jsonObject.put("type", imageFile.second)
                jsonObject.put("name", imageFile.third)
                jsonObject.put("blob", imageFile.first)
                jsonArray.put(jsonObject)
            }

            val jsonData = """
                {
                    "method": "upload_files_from_app",
                    "result": {
                        "imageFiles": $jsonArray
                    }
                }
            """.trimIndent()

            val jsonObject = JSONObject(jsonData)
            val jsonObjectString = jsonObject.toString()
            Log.d("WebViewBridge", "JSBridge JSON Object: $jsonObjectString")

            // Call JavaScript function with JSON data
            webView.evaluateJavascript("javascript: window.mobile2web.onMessage($jsonObjectString)", null)
        }
android kotlin mobile memory-management out-of-memory
1个回答
0
投票

将图像转换为base64字符串效率不高,并且会占用大量内存,因为整个图像都放入内存中。

根据图像的大小,您一次只能发送几张图像。

当您尝试将这些图像发送到 webview 时,尚不清楚您如何处理这些图像,但如果您尝试将它们上传到服务器,则不应通过 base64 字符串上传它们

© www.soinside.com 2019 - 2024. All rights reserved.