代码之家  ›  专栏  ›  技术社区  ›  HelloCW

如何在Kotlin中传递除参数之外的方法?

  •  0
  • HelloCW  · 技术社区  · 4 年前

    我希望通过一个实现 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 ?    
                }
            }
        }    
    }
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   Sergio    4 年前

    这个 Code A 在传递lambda作为参数方面看起来不错。但我会做一些改进。

    我会用 MediaRecorder 在一个类中,例如。 RecordService , HomeViewModel 不需要知道什么工具 RecordService 用于制作记录。如果您需要对记录器的事件做出反应,您可以为此创建一个额外的接口。具有所有接口和事件的示例代码如下所示:

    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 */ }
            }
        }
    }
    

    与其使用具体的实现,不如使用接口。我也不建议使用 m 前缀命名变量时,它是 Java语言 语言,而不是 Kotlin 。

    P.S。 Flow 可用于发出记录器的事件,而不是 RecordServiceEventListener ,但这是另一回事:)

        2
  •  0
  •   Kemal Cengiz    4 年前

    给你:

    class HomeViewModel(...) : AndroidViewModel(mApplication) {
        //I save  mOnInfoListener to memory ?
        val mOnInfoListener = object : MediaRecorder.OnInfoListener {
            override fun onInfo(mr: MediaRecorder, what: Int, extra: Int) {
                if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
                    stopRecord()
                }
            }
        }
    
    
        fun startRecord() {
            startRecord(savedfilename)
        }
    
    }
    
    
    class RecordService(private val mOnInfoListener: MediaRecorder.OnInfoListener) : Service() {
    
        fun startRecord(filename: String) {
            val mRecorder = MediaRecorder()
            mRecorder.setOnInfoListener(mOnInfoListener)  //  I get mOnInfoListener from memory ?
        }
    }