我如何在Kotlin传递一个方法除了参数?



我希望传递一个实现MediaRecorder.OnInfoListener的方法。

目前我使用代码A来传递实现MediaRecorder.OnInfoListener的方法。

还有别的方法吗?也许就像代码b一样。

代码

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使用什么工具来制作记录。如果你需要对记录器的事件作出反应,你可以为此创建一个额外的接口。带有所有接口和事件的示例代码如下所示:

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.

注:Flow可以用来发出记录器的事件,而不是RecordServiceEventListener,但这是另一个故事:)

给你:

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

相关内容

  • 没有找到相关文章

最新更新