使用暴力方式解決閃退問題:加大ViewPager可以容許的page數量

This commit is contained in:
Raymond Yang 2023-03-06 09:31:20 +08:00
parent d8d351831c
commit ed8f2a7c0f
3 changed files with 36 additions and 35 deletions

View File

@ -65,27 +65,19 @@ class MainActivity : AppCompatActivity() {
viewPager.apply { viewPager.apply {
adapter = splitVideoViewAdapter adapter = splitVideoViewAdapter
offscreenPageLimit = 1 offscreenPageLimit = 100
setPageTransformer(null) setPageTransformer(null)
registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() { registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
private var oldPage = 0 private var oldPage = 0
override fun onPageScrollStateChanged(state: Int) { override fun onPageScrollStateChanged(state: Int) {
super.onPageScrollStateChanged(state) super.onPageScrollStateChanged(state)
if (state == ViewPager2.SCROLL_STATE_DRAGGING) { /*if (state == ViewPager2.SCROLL_STATE_DRAGGING) {
oldPage = currentPage oldPage = currentPage
splitVideoViewAdapter.stop(currentPage) splitVideoViewAdapter.stop(currentPage)
} }
if (state == ViewPager2.SCROLL_STATE_IDLE && currentPage == oldPage) { if (state == ViewPager2.SCROLL_STATE_IDLE && currentPage == oldPage) {
splitVideoViewAdapter.play(currentPage) splitVideoViewAdapter.play(currentPage)
} }*/
/*Log.d("Split", "onPageScrollStateChanged: ${
when(state) {
ViewPager2.SCROLL_STATE_IDLE -> "SCROLL_STATE_IDLE"
ViewPager2.SCROLL_STATE_DRAGGING -> "SCROLL_STATE_DRAGGING"
ViewPager2.SCROLL_STATE_SETTLING -> "SCROLL_STATE_SETTLING"
else -> ""
}
}")*/
//Log.d("Split", "oldPage: $oldPage, currentPage: $currentPage") //Log.d("Split", "oldPage: $oldPage, currentPage: $currentPage")
} }
override fun onPageScrolled( override fun onPageScrolled(

View File

@ -57,38 +57,42 @@ class SplitViewFragment : Fragment() {
initView() initView()
viewModel.activePage.observe(viewLifecycleOwner) { /*viewModel.activePage.observe(viewLifecycleOwner) {
if (it == null) return@observe if (it == null) return@observe
if (it == this.mPageNum) { if (it == this.mPageNum) {
playAll() MainScope().launch {
//delay(1000)
//playAll()
}
} else { } else {
stopAll() //stopAll()
} }
} }*/
} }
override fun onPause() { override fun onPause() {
stopAll() //stopAll()
super.onPause() super.onPause()
Log.d("${TAG}_$mPageNum", "onPause()") Log.d("${TAG}_$mPageNum", "onPause()")
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (viewModel.activePage.value == mPageNum) { //if (viewModel.activePage.value == mPageNum) {
MainScope().launch { MainScope().launch {
delay(splitMode * Constants.CONF_DELAY_BASE_MILLIS) //delay(splitMode * Constants.CONF_DELAY_BASE_MILLIS)
playAll() playAll()
} }
} //}
Log.d("${TAG}_$mPageNum", "onResume()") Log.d("${TAG}_$mPageNum", "onResume()")
} }
/*override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
destroyAll() //destroyAll()
stopAll()
Log.d("${TAG}_$mPageNum", "onDestroy()") Log.d("${TAG}_$mPageNum", "onDestroy()")
}*/ }
private fun initView() { private fun initView() {
// 生成 VideoView 分割畫面 // 生成 VideoView 分割畫面
@ -164,7 +168,7 @@ class SplitViewFragment : Fragment() {
MainScope().launch { MainScope().launch {
stopAll() stopAll()
//delay(splitMode * Constants.CONF_DELAY_BASE_MILLIS) //delay(splitMode * Constants.CONF_DELAY_BASE_MILLIS)
delay((splitMode * 100) + Constants.CONF_DELAY_BASE_MILLIS) //delay((splitMode * 100) + Constants.CONF_DELAY_BASE_MILLIS)
val item = data[position] val item = data[position]
val bundle = Bundle().apply { val bundle = Bundle().apply {
//putInt(MonitoringActivity.BUNDLE_DEVICE_ID, item.id) //putInt(MonitoringActivity.BUNDLE_DEVICE_ID, item.id)
@ -191,32 +195,34 @@ class SplitViewFragment : Fragment() {
} }
} }
fun playAll() = MainScope().launch(Dispatchers.Main) { fun playAll() /*= MainScope().launch(Dispatchers.Main)*/ {
if (videoViews.isEmpty()) return@launch if (videoViews.isEmpty()) return
//delay(splitMode * Constants.CONF_DELAY_BASE_MILLIS)
for (index in data.indices) { for (index in data.indices) {
if (!videoViews[index].isReady) continue
videoViews[index].resetRetryCount() videoViews[index].resetRetryCount()
videoViews[index].play() videoViews[index].play()
delay(300) //delay(300)
} }
}.start() }//.start()
fun stopAll() = MainScope().launch(Dispatchers.Main) { fun stopAll() /*= MainScope().launch(Dispatchers.Main)*/ {
if (videoViews.isEmpty()) return@launch if (videoViews.isEmpty()) return
for (index in data.indices) { for (index in data.indices) {
videoViews[index].stopRetryCount() videoViews[index].stopRetryCount()
if (!videoViews[index].isPlaying || videoViews[index].isLoading) continue if (!videoViews[index].isPlaying || videoViews[index].isLoading) continue
videoViews[index].stop() videoViews[index].stop()
delay(100) //delay(300)
} }
}.start() }//.start()
fun destroyAll() = MainScope().launch(Dispatchers.Main) { fun destroyAll() /*= MainScope().launch(Dispatchers.Main)*/ {
if (videoViews.isEmpty()) return@launch if (videoViews.isEmpty()) return
for (index in data.indices) { for (index in data.indices) {
videoViews[index].destroy() videoViews[index].destroy()
delay(100) //delay(100)
} }
}.start() }//.start()
companion object { companion object {
private val TAG = SplitViewFragment::class.java.simpleName private val TAG = SplitViewFragment::class.java.simpleName

View File

@ -36,6 +36,8 @@ class VideoView : ConstraintLayout, GstCallback {
private var data: Device? = null private var data: Device? = null
var isReady: Boolean = false
var isLoading: Boolean = false var isLoading: Boolean = false
set(value) { set(value) {
view.pbLoading.isVisible = value view.pbLoading.isVisible = value
@ -132,6 +134,7 @@ class VideoView : ConstraintLayout, GstCallback {
override fun onStatus(gstStatus: GstStatus?) { // onStatus 不是在主執行緒,因此透過 Handler 發訊息到主執行緒去執行 override fun onStatus(gstStatus: GstStatus?) { // onStatus 不是在主執行緒,因此透過 Handler 發訊息到主執行緒去執行
when (gstStatus) { when (gstStatus) {
GstStatus.READY -> isReady = true
GstStatus.PLAYING -> mHandler.sendMessage(Message().apply { what = MSG_PLAY }) GstStatus.PLAYING -> mHandler.sendMessage(Message().apply { what = MSG_PLAY })
GstStatus.PAUSE -> mHandler.sendMessage(Message().apply { what = MSG_PAUSE }) GstStatus.PAUSE -> mHandler.sendMessage(Message().apply { what = MSG_PAUSE })
//GstStatus.ERROR_WHEN_OPENING -> mHandler.sendMessage(Message().apply { what = MSG_PAUSE }) //GstStatus.ERROR_WHEN_OPENING -> mHandler.sendMessage(Message().apply { what = MSG_PAUSE })