android - 如何在 Kotlin 中传递方法接受参数?

标签 android kotlin mvvm listener android-viewmodel

我希望通过一个实现 MediaRecorder.OnInfoListener 的方法.
目前我使用代码A传递实现MediaRecorder.OnInfoListener的方法.
还有其他方法吗?也许就像代码 B 一样。
代码 A

class HomeViewModel(...) : AndroidViewModel(mApplication) {

    fun startRecord() {
        startRecord(savedfilename){
             mr, what, extra ->
                 if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
                     stopRecord()
                 }            
        }

    }

}


class RecordService : Service() {  

    fun startRecord(filename:String, mOnInfoListener: MediaRecorder.OnInfoListener){
       mRecorder = MediaRecorder()
        mRecorder?.let {    
            with(it) {                  
                setOnInfoListener(mOnInfoListener)    
            }
        }
    }    
}
代码 B
class HomeViewModel(...) : AndroidViewModel(mApplication) {

{
    //I save  mOnInfoListener to memory ?   
    val mOnInfoListener = object: MediaRecorder.OnInfoListener{
        mr, what, extra ->
           if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
              stopRecord()
          }
    }

    fun startRecord() {
        startRecord(savedfilename)    
    }

}


class RecordService : Service() {  

    fun startRecord(filename:String){
       mRecorder = MediaRecorder()
        mRecorder?.let {    
            with(it) {
                setOnInfoListener(mOnInfoListener)  //  I get mOnInfoListener from memory ?    
            }
        }
    }    
}

最佳答案

Code A在传递 lambda 作为参数方面看起来不错。但我会做一些改进。
我会用 MediaRecorder 封装这项工作在一类中,例如RecordService , HomeViewModel不需要知道什么工具RecordService用来做记录。如果您需要对记录器的事件使用react,您可以为此创建一个额外的界面。包含所有接口(interface)和事件的示例代码如下所示:

sealed interface Event
object MaxDurationReachedEvent : Event
//... create another events if need

interface RecordServiceEventListener {
    fun onRecordEvent(event: Event)
}

interface RecordService {
    fun startRecord(filename: String)
    fun registerEventListener(listener: RecordServiceEventListener)
    fun unregisterEventListener(listener: RecordServiceEventListener)

}

class RecordServiceImpl : Service(), RecordService {

    private var recorder: MediaRecorder? = null
    private var eventListeners: MutableList<RecordServiceEventListener> = mutableListOf()

    override fun startRecord(filename: String) {
        recorder = MediaRecorder()
        recorder?.setOnInfoListener { mr, what, extra ->
            if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
                eventListeners.forEach { it.onRecordEvent(MaxDurationReachedEvent) }
            }
        }
    }

    override fun registerEventListener(listener: RecordServiceEventListener) {
        eventListeners.add(listener)
    }

    override fun unregisterEventListener(listener: RecordServiceEventListener) {
        eventListeners.remove(listener)
    }
}

class HomeViewModel(private val recordService: RecordService) : ViewModel(), RecordServiceEventListener {

    init {
        recordService.registerEventListener(this)
    }

    override fun onCleared() {
        recordService.unregisterEventListener(this)
    }

    fun startRecord() {
        recordService.startRecord(savedFilename)
    }

    override fun onRecordEvent(event: Event) {
        when (event) {
            MaxDurationReachedEvent -> { ... /* Do something */ }
        }
    }
}
最好使用接口(interface)而不是具体的实现。我也不建议使用 m命名变量时的前缀,样式为 java 语言,而不是 Kotlin .
附言Flow可用于发出记录器的事件而不是 RecordServiceEventListener ,但这是另一个故事:)

关于android - 如何在 Kotlin 中传递方法接受参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72135773/

相关文章:

android - AWSAppSyncClient 不检测 graphql 查询

android - 如何从android获取新的经纬度坐标

java - 如何在 View 上设置背景而不影响其尺寸?

java - 在 Kotlin 中覆盖 Java @Nullable varargs 方法,IDE 提示它没有覆盖任何内容

kotlin - Kotlin 数据类的属性包含/排除

android - 如何使用 sharedview 模型 koin android 注入(inject)具有作用域的 View 模型

Android 工作人员被取消,没有显示原因

wpf - MVVM 的命名约定?

ios - 如何将测试数据添加到PreviewProvider

android - 从 Fragment 构建单个插入事件的正确方法