Bug MP4视频第二次下载导致APP崩溃 原因是第一次保存时缓存文件被删除导致再次保存找不到文件
在最外层判断当前视频是否是MP4,如果是直接返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 suspend fun saveVideoToGallery (context: Context , clip: Clip ) : String { if (clip.type != Clip.CLIP_TYPE_ORIGINAL_DATA) { logger.w(TAG, "clip type is not original data" ) val nonOriMP4Path = clip.nonOriginalData?.get (Clip.NonOriginalData.KEY_MP4_PATH) return if (nonOriMP4Path != null && File(nonOriMP4Path).exists()) { copyToMediaStore(context, File(nonOriMP4Path)) } else { "" } } return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { saveVideoBeforeQ(context, clip) } else { saveVideo(context, clip) } }
其中copyToMediaStore(context, File(nonOriMP4Path))
是用于将视频拷贝到相册
续9.11 收藏列表跳转到播放后返回定位到当前播放的位置 静态变量和静态方法的写法不优雅 改成StartActivityForResult
的方式
VideoFlowViewModel
中传递position
的值并在SearchResultFlowActivity
中观察
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private fun setPlayerClipDatasource ( player: IjkMediaPlayer , clip: Clip , listener: RawPacketVideoSource .TimeListener ? = null , timeOffset: Long = 0 , position: Int ) { logger.i(TAG, "setPlayerClipDatasource, $clip " ) uiActionUpdateClipPositionLiveData.postValue( UiAction( ACTION_UPDATE_CLIP_POSITION, position ) ) }
观察到的时候返回result
的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 flowVM.uiActionUpdateClipPositionLiveData.observe(this ) { action -> if (action == null ) return @observe when (action.what) { VideoFlowViewModel.ACTION_UPDATE_CLIP_POSITION -> { (action.param as ? Int )?.let { position -> val resultIntent = Intent().putExtra( BaseNavigation.Constants.EXTRA_CURRENT_CLIP_POSITION, position ) setResult(Activity.RESULT_OK, resultIntent) } } else -> { logger.w(TAG, "uiActionRequiredEvent, unknown action $action " ) } } }
FavoriteAdapter
中通过onClick
传递当前点击的不包含的日期位置下标,用于跳转的时候从第几个视频开始播放
1 2 3 4 5 fun onClickFavoriteItem (positionInGroup: Int ) { val clipsListJsonString = gson.toJson(favoriteList) pv.store(EXTRA_FLOW_CLIPS_ARRAY_JSON, clipsListJsonString) uiActionRequiredEvent.postValue(UiAction(ACTION_CLICK_FAVORITE_ITEM, positionInGroup)) }
FavoriteFragment
中接收值并执行相应操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 private var currentClipPosition: Int = 0 private var startFavoriteFlowLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { currentClipPosition = result.data ?.getIntExtra( BaseNavigation.Constants.EXTRA_CURRENT_CLIP_POSITION, 0 ) ?: 0 } else { logger.e(TAG, "startFavoriteFlowLauncher code=${result.resultCode} " ) } } viewModel.uiActionRequiredEvent.observe(viewLifecycleOwner) { it ?: return @observe when (it.what) { ACTION_CLICK_FAVORITE_ITEM -> { val positionInGroup = it.param as ? Int val intent = Intent(context, SearchResultFlowActivity::class .java) intent.putExtra( BaseNavigation.Constants.EXTRA_FLOW_INITIAL_POSITION_INT, positionInGroup ) intent.putExtra(BaseNavigation.Constants.EXTRA_FLOW_NEXT_CURSOR_STRING, "" ) startFavoriteFlowLauncher.launch(intent) } } }
滚动方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 private fun scrollViewToLastClip (recyclerView: RecyclerView , layoutManager: GridLayoutManager ) { val positionWithDate = viewModel.searchResultAdapter.countDateBeforeClip(currentClipPosition) if (positionWithDate > 0 ) { if (recyclerView.layoutManager == null || recyclerView.adapter == null ) { logger.d(TAG, "RecyclerView layout or adapter is not set" ) return } val lastVisiblePosition = layoutManager.findLastVisibleItemPosition() val rowHeight = if (positionWithDate < lastVisiblePosition) { layoutManager.findViewByPosition(positionWithDate)?.bottom } else { resources.displayMetrics.heightPixels } recyclerView.scrollToPosition(positionWithDate) val scrollDistance = MeasureUtil.dp2px(context, 24f + 48f + 16f + 96f + 4f ) logger.d(TAG, "onResume height: $rowHeight padding $scrollDistance " ) if (rowHeight != null ) { binding.recyclerView.smoothScrollBy(0 , rowHeight - scrollDistance) } } }
方法写在onResume
里存在问题:在滚动后回到收藏页并往下翻视频列表,此时退出app到后台,再次切入应用会触发onResume
导致再次滚动
把滚动方法写到接收到result
的时候
FavoriteFragment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private var startFavoriteFlowLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val currentClipPosition = result.data ?.getIntExtra( BaseNavigation.Constants.EXTRA_CURRENT_CLIP_POSITION, 0 ) ?: 0 scrollViewToLastClip(binding.recyclerView, layoutManager, currentClipPosition) } else { logger.e(TAG, "startFavoriteFlowLauncher code=${result.resultCode} " ) } }