android - 在附加的堆栈跟踪中获取了资源但从未释放 - kotlin
问题描述
我正在使用 camera2 并收到以下异常:
04-13 20:39:54.801 13097-13110/com.x.y.z E/StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
java.lang.Throwable: Explicit termination method 'release' not called
at dalvik.system.CloseGuard.open(CloseGuard.java:184)
at android.view.Surface.setNativeObjectLocked(Surface.java:460)
at android.view.Surface.<init>(Surface.java:152)
at android.media.ImageReader.nativeGetSurface(Native Method)
at android.media.ImageReader.<init>(ImageReader.java:130)
at android.media.ImageReader.newInstance(ImageReader.java:100)
at androidx.camera.core.MetadataImageReader.createImageReaderProxy(MetadataImageReader.java:124)
at androidx.camera.core.MetadataImageReader.<init>(MetadataImageReader.java:113)
at androidx.camera.core.ImageCapture.createPipeline(ImageCapture.java:335)
at androidx.camera.core.ImageCapture.onSuggestedResolutionUpdated(ImageCapture.java:974)
at androidx.camera.core.UseCase.updateSuggestedResolution(UseCase.java:372)
at androidx.camera.core.CameraX.bindToLifecycle(CameraX.java:321)
at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:229)
at com.x.y.z.fragments.CameraFragment$bindCameraUseCases$1.run(CameraFragment.kt:286)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5651)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
查看堆栈跟踪表明它来自尚未发布的 SurfaceView。检查参考表明在 Java 中你必须释放它;不太清楚如何在 Kotlin 中处理它。
顺便说一句,我稍微修改了 CameraXBasic,以便在触摸图库按钮时运行以下代码:
// Listener for button used to view the most recent photo
camControls.findViewById<ImageButton>(R.id.photo_view_button).setOnClickListener {
pickFromGallery()
}
private fun pickFromGallery() {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
val mimeTypes =
arrayOf("image/jpeg", "image/png")
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
startActivityForResult(intent, GALLERY_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && requestCode == GALLERY_REQUEST_CODE){
val selectedUri = data?.data
val filePathColumn = MediaStore.Images.Media.DATA
val cursor = context?.contentResolver?.query(selectedUri!!, arrayOf(filePathColumn), null, null, null)
cursor?.moveToFirst()
val columnIndex = cursor?.getColumnIndex(filePathColumn)
val absolutePath = cursor?.getString(columnIndex!!)
cursor?.close()
if(absolutePath != null) setImagePathAndPopBack(File(absolutePath))
}
}
此代码正确显示了选择图片库的选项,但如果我只是触摸外部以将其关闭,应用程序会因上述异常而崩溃。重现它的可靠方法是触摸图库图标并在不打开任何照片库的情况下将其关闭几次。只是为了清楚说明 onActivityResult 的大部分代码都没有执行,因为我什至没有选择任何图像。
构建.gradle:
implementation "androidx.camera:camera-core:1.0.0-beta02"
implementation "androidx.camera:camera-camera2:1.0.0-beta02"
implementation "androidx.camera:camera-lifecycle:1.0.0-beta02"
implementation "androidx.camera:camera-view:1.0.0-alpha09"
安卓工作室:3.6.2 科特林:1.3.61
提前感谢您的帮助!
编辑1:
我意识到只有在使用 StrictMode 时才会发生这种情况
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build()
)
如果我运行我的代码而不使用惩罚死亡(),那么它的工作原理与示例一样顺利。
解决方案
我发现的解决方法是避免因泄漏可关闭对象而导致死刑。这个错误似乎来自 Android API,我已将其指向 Android 开发人员,他们选择不采取行动。
推荐阅读
- javascript - 优雅的百分比几何分布函数(Javascript)
- javascript - React.js:props.state 为空白(空)
- pentaho - 索引功能:Pentaho 数据集成
- java - 显示错误“ViewHolder”是无法实例化的抽象类
- node.js - 通过注册大量帐户来防止恶意用户填充我的数据库?
- javascript - 计算隐藏的 div
- javascript - Javascript-Arrays:获取以字母开头的第一项的索引
- c++ - 在 Clang 中的两个源位置之间复制源代码
- c++ - 将矩阵附加到 stl 矩阵(2d std::vector)
- c# - Richtextbox 多种背景颜色