如何通过Kotlin中的参数除外的方法?

发布于 2025-01-26 13:05:05 字数 1612 浏览 4 评论 0原文

我希望通过一种实现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 ?    
            }
        }
    }    
}

I hope to pass a method which implement MediaRecorder.OnInfoListener.

At present I use Code A to pass the method which implement MediaRecorder.OnInfoListener.

Is there any other way to do it? maybe just like Code B.

Code 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)    
            }
        }
    }    
}

Code 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 ?    
            }
        }
    }    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓦然回首 2025-02-02 13:05:05

代码A在将lambda作为参数传递方面看起来不错。但是我会做出一些改进。

I would encapsulate the work with MediaRecorder in one class, eg RecordService, HomeViewModel doesn't need to know anything about what tools 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

PS Flow可用于发射录音机的事件,而不是RecordserviceEventListener,但这是另一个故事:)

The Code A looks good in terms of passing a lambda as parameter. But I would make a couple of improvements.

I would encapsulate the work with MediaRecorder in one class, e.g. RecordService, HomeViewModel doesn't need to know anything about what tools RecordService uses to make records. And if you need to react on recorder's events you can create an additional interface for that. The sample code with all interfaces and events will look like the following:

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

It is better to work with interfaces rather than with concrete implementations. Also I wouldn't suggest to use m prefix when naming variables, it is a style of Java language, not Kotlin.

P.S. Flow can be used to emit events of a recorder instead of RecordServiceEventListener, but this is another story :)

画骨成沙 2025-02-02 13:05:05

干得好:

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 ?
    }
}

Here you go:

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 ?
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文