MediaMetadataRetriever执行102次请求后抛出0x80000000异常的解决方法
问题:MediaMetadataRetriever 处理102次后抛出setDataSource异常,需重启进程解决
我需要检查所有MP3文件是否包含Android系统可读取的有效图片。为此遍历MediaStore.Audio.Media中的所有条目,通过MediaMetadataRetriever的setDataSource()和getEmbeddedPicture()方法获取封面。该操作在Pixel 8设备上前102次执行正常,但之后setDataSource()会抛出以下异常:
java.lang.RuntimeException: setDataSource failed: status = 0x80000000 at android.media.MediaMetadataRetriever._setDataSource(Native Method) at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:310) at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:253) at org.richinet.checkmusicimages.MainActivity.checkMetadata(MainActivity.kt:108) at org.richinet.checkmusicimages.MainActivity.scanMusic(MainActivity.kt:100) at org.richinet.checkmusicimages.MainActivity.checkPermissionsAndScan(MainActivity.kt:72) at org.richinet.checkmusicimages.MainActivity.onCreate(MainActivity.kt:59) at android.app.Activity.performCreate(Activity.java:9290) at android.app.Activity.performCreate(Activity.java:9268) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1543) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4503) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4723) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:224) at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133) at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2987) at android.os.Handler.dispatchMessageImpl(Handler.java:142) at android.os.Handler.dispatchMessage(Handler.java:125) at android.os.Looper.loopOnce(Looper.java:269) at android.os.Looper.loop(Looper.java:367) at android.app.ActivityThread.main(ActivityThread.java:9333) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929)
我尝试了多种解决方案,但均无效,只有重启应用才能重新获得处理102次请求的能力:
- 将请求速度降至每秒1次,确保资源可通过
.release()回收 - 分块处理请求,每块处理后等待20秒
- 将分块任务放到单独进程中执行
- 复用
MediaMetadataRetriever实例 - 每次请求新建
MediaMetadataRetriever实例 - 每次请求后调用GC
我希望使用原生MediaMetadataRetriever而非第三方库,以确保适配原生Android设备。Gemini指出可能是Binder和原生C++函数未释放资源,请问如何在执行80次测试后重启原生进程?
以下是我的测试代码:
private fun scanMusic() { val projection = arrayOf( MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA ) val cursor = contentResolver.query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, null, null, null ) cursor?.use { val dataColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA) val nameColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME) while (it.moveToNext()) { val path = it.getString(dataColumn) val name = it.getString(nameColumn) checkMetadata(path, name) } } } private fun checkMetadata(path: String, name: String) { val retriever = MediaMetadataRetriever() try { retriever.setDataSource(path) val art = retriever.embeddedPicture if (art != null) { musicResults.add("OK: $name (Size: ${art.size} bytes)") okCount++ if (okCount > 0 && okCount % 100 == 0) logCounts() } else { musicResults.add("NO ART: $name") noArtCount++ if (noArtCount > 0 && noArtCount % 100 == 0) logCounts() } } catch (e: Exception) { musicResults.add("ERROR: $name - ${e.message}") errorCount++ if (errorCount > 0 && errorCount % 100 == 0) logCounts() //Log.e("MusicScanner", "Error reading $path", e) } finally { retriever.release() } }
日志示例:
OK: 102, No Art: 42, Errors: 900
内容的提问来源于stack exchange,提问作者richardeigenmann
相关产品推荐
相关产品推荐

