Android MediaPlayer调用openFd时崩溃问题求助
解决MediaPlayer加载资产文件时的崩溃问题
我正试图通过图片属性为MediaPlayer设置显示边界,但执行requireContext().assets.openFd(imagename)代码行时应用崩溃,相关代码及崩溃日志如下:
相关代码
player = MediaPlayer().apply { requireContext().assets.openFd(imagename) .use { descriptor -> val metadataRetriever = MediaMetadataRetriever() metadataRetriever.setDataSource( descriptor.fileDescriptor, descriptor.startOffset, descriptor.length ) val videoWidth = metadataRetriever.extractMetadata(METADATA_KEY_VIDEO_WIDTH) ?.toFloatOrNull() ?: 0f val videoHeight = metadataRetriever.extractMetadata(METADATA_KEY_VIDEO_HEIGHT) ?.toFloatOrNull() ?: 0f val videoRotation = metadataRetriever.extractMetadata(METADATA_KEY_VIDEO_ROTATION) ?.toFloatOrNull() ?: 0f // 处理视频旋转,确保缩放逻辑计算正确 val imageSize = RectF(0f, 0f, augmentedImage.extentX, augmentedImage.extentZ) .transform(rotationMatrix(videoRotation)) val videoScaleType = VideoScaleType.CenterCrop videoAnchorNode.setVideoProperties( videoWidth = videoWidth, videoHeight = videoHeight, videoRotation = videoRotation, imageWidth = imageSize.width(), imageHeight = imageSize.height(), videoScaleType = videoScaleType ) }
崩溃日志
FATAL EXCEPTION: main Process: io.github.sceneview.sample.araugmentedimage, PID: 2250 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) Caused by: java.io.FileNotFoundException: qrcode at android.content.res.AssetManager.nativeOpenAssetFd(Native Method) at android.content.res.AssetManager.openFd(AssetManager.java:1011) at io.github.sceneview.sample.araugmentedimage.MainFragment$onViewCreated$1$2.invoke(MainFragment.kt:77) at io.github.sceneview.sample.araugmentedimage.MainFragment$onViewCreated$1$2.invoke(MainFragment.kt:59) at io.github.sceneview.ar.ARSceneView.onSessionUpdated(ARSceneView.kt:324) at io.github.sceneview.ar.ARSceneView.onFrame(ARSceneView.kt:278) at io.github.sceneview.SceneView$frameCallback$1.doFrame(SceneView.kt:295) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1687) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1698) at android.view.Choreographer.doCallbacks(Choreographer.java:1153) at android.view.Choreographer.doFrame(Choreographer.java:1069) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1646) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:230) at android.os.Looper.loop(Looper.java:319) at android.app.ActivityThread.main(ActivityThread.java:8919) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
解决思路
从崩溃日志的核心错误java.io.FileNotFoundException: qrcode可以看出,是找不到名为qrcode的资产文件,按以下步骤排查修复:
- 检查文件存在性:确认
qrcode文件确实放在项目的src/main/assets目录下,注意Android资产文件名区分大小写,如果实际文件名是QRCode或带后缀(比如qrcode.mp4),要完全匹配。 - 确认文件路径:如果文件在assets的子目录中(比如
assets/videos/qrcode),需要传入完整的相对路径"videos/qrcode",而不是仅传"qrcode"。 - 验证文件有效性:确保
qrcode是MediaPlayer支持的媒体格式(如MP4、3GP等),没有损坏。 - 添加异常处理:在代码中捕获
FileNotFoundException,避免应用崩溃同时方便排查问题,示例:
player = MediaPlayer().apply { try { requireContext().assets.openFd(imagename).use { descriptor -> // 原有逻辑代码 } } catch (e: FileNotFoundException) { Log.e("MediaPlayer", "资产文件不存在: $imagename", e) } }
- 检查打包配置:确认项目的build.gradle文件中没有排除该资产文件,默认Android会打包assets目录下的所有文件,若有自定义打包规则需确保
qrcode被包含。
内容的提问来源于stack exchange,提问作者CYAD
相关产品推荐
相关产品推荐

