Это выглядит правильно, но вы создали два ненужных слоя сопрограммы вокруг вашего l oop. В setTimeOnProgressBar()
вы завернули свою сопрограмму в новую coroutineScope
, которую вы ни для чего не используете. Это может быть удалено, и тогда это вообще не должно быть функцией приостановки. И поэтому вы также можете удалить сопрограмму, в которую вы поместили вызов setTimeOnProgressBar()
, в initPositionBar()
.
Кроме того, вы воссоздали набор шаблонов, уже предоставленных библиотекой Android ktx. , Уже есть свойство расширения lifecycleScope
, которое можно использовать для запуска сопрограмм, и оно автоматически отменяется в onDestroyView()
. Поэтому вам не нужно создавать родительское задание или переопределять coroutineContext
или отменять родительское задание.
Вы можете использовать lifecycleScope.launch
при запуске сопрограмм.
class BookViewFragment : Fragment() {
private var _binding: FragmentBookViewerBinding? = null
private val bookViewFragmentBinding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentBookViewerBinding.inflate(layoutInflater)
val view = bookViewFragmentBinding.root
initMediaPlayer()
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
mp.stop()
mp.release()
}
private fun initMediaPlayer() {
mp = MediaPlayer()
mp.run {
setDataSource(...)
setVolume(0.5f, 0.5f)
prepare()
}
totalTime = mp.duration
initPositionBar()
}
private fun initPositionBar() {
bookViewFragmentBinding.mediaPosition.max = totalTime
setTimeOnProgressBar()
}
private fun setTimeOnProgressBar() {
lifecycleScope.launch {
var progress = mp.currentPosition
while (progress < mp.duration) {
progress = mp.currentPosition
bookViewFragmentBinding.mediaPosition.progress = progress
val timePlayed = progress
val timeLeft = mp.duration - timePlayed
bookViewFragmentBinding.timePlayed.text = formatIntToTime(timePlayed)
bookViewFragmentBinding.timeLeft.text =
getString(R.string.time_left, formatIntToTime(timeLeft))
delay(1000)
}
}
}
}