You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hilt创建的MediaRecorder实例在Android应用关闭时会自动释放吗?

问题

在Android Studio项目中采用Hilt作为依赖注入框架,通过如下Code A自动创建MediaRecorder实例,HandleMeter类可自动注入并使用该MediaRecorder实例。请问当关闭应用时,Hilt是否会自动释放该MediaRecorder实例?

代码A

@InstallIn(SingletonComponent::class)
@Module
object ObjectModule {
    @Provides
    @Singleton
    fun provideMediaRecorder(): MediaRecorder {
        return  MediaRecorder()
    }
}

代码B

class HandleMeter @Inject constructor(
    @ApplicationContext private val appContext: Context,
    private val mRecorder: MediaRecorder
): IHandleMeter {

    private fun startRecord(actionMax: () -> Unit){
        with(mRecorder) {
            setAudioSource(MediaRecorder.AudioSource.MIC);
            ...
            prepare()
            start()
        }
    }

    private fun stopRecord(){
        try {            
            mRecorder.stop()
        } catch (e: Exception) {
        }
    }
}
回答

Hilt不会自动释放这个MediaRecorder实例,原因如下:

  • 你通过@Singleton和@InstallIn(SingletonComponent::class)将MediaRecorder实例绑定到了应用全局单例组件,它的生命周期和应用进程一致,只有当应用进程被系统销毁时,该实例才会被垃圾回收,但这不属于主动释放资源的范畴。
  • Hilt仅负责依赖实例的创建与注入,不会自动管理Android原生组件的资源释放——MediaRecorder作为持有硬件资源(麦克风)的原生类,必须手动调用其release()方法才能真正释放占用的系统资源。
  • 目前你的代码中仅调用了stop(),但stop()只是停止录制,并未释放底层资源,若不调用release(),可能导致资源泄漏,影响后续其他应用使用麦克风。

解决方案建议

  1. 让HandleMeter实现LifecycleObserver,监听应用生命周期事件,在应用销毁时调用mRecorder.release():
class HandleMeter @Inject constructor(
    @ApplicationContext private val appContext: Context,
    private val mRecorder: MediaRecorder
): IHandleMeter, LifecycleObserver {

    // ...原有代码...

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun releaseRecorder() {
        try {
            mRecorder.release()
        } catch (e: Exception) {
            // 捕获异常避免崩溃
        }
    }
}

然后在Application类中添加观察者:

@HiltAndroidApp
class MyApp : Application() {
    @Inject lateinit var handleMeter: HandleMeter

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(handleMeter)
    }
}
  1. 或者在HandleMeter中暴露一个手动释放的方法,在合适的时机(比如最后一个使用该实例的页面销毁时)调用:
class HandleMeter @Inject constructor(
    private val mRecorder: MediaRecorder
): IHandleMeter {
    // ...原有代码...

    fun release() {
        try {
            mRecorder.release()
        } catch (e: Exception) {
        }
    }
}

内容的提问来源于stack exchange,提问作者HelloCW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:02:41