我有一个小应用程序,其中包含一个处理图片的网站。我无法从手机上传超过 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)
}
将图像转换为base64字符串效率不高,并且会占用大量内存,因为整个图像都放入内存中。
根据图像的大小,您一次只能发送几张图像。
当您尝试将这些图像发送到 webview 时,尚不清楚您如何处理这些图像,但如果您尝试将它们上传到服务器,则不应通过 base64 字符串上传它们