我希望传递一个实现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 ?
}
}