Android·VideoView使用中因为主线程冲突遇到的坑

因为一个业务场景需要用到A-B-C-D四个方法(代码块)
我在三台设备上测试,在其中两台设备上(API22和API29)运行没有问题,代码按照A->B->C->D顺序执行
但是在另一台设备(API19)上运行时变成了A->C->D->B的顺序

具体原因我初步分析了以下几点

  • CPU的频率或者API版本的影响,导致线程时间被占用
  • 因为AB是作为一个整体,C是另外一个线程,存在互相冲突可能
  • 因为执行view.setVisibility(View.VISIBLE)耗时太长,导致AB线程时间用完,C线程已经启动,导致AB线程中断
  • C线程执行完后,又回头接着执行AB线程未执行完的B部分
  • 所以导致了ACDB的执行顺序
    代码如下:

A部分

	省略业务代码...
	view.setVisibility(View.VISIBLE);// 显示播放器

B部分

	省略业务代码...
	videoPlay = true;// 播放标志打开
	view.start();// 开始播放

C部分

	setOnErrorListener监听{
		调用D方法
	}

D部分

	视频的关闭以及其他操作的业务代码

结合业务代码,再来看问题

  1. C的作用其实主要是在出错时调用D
  2. B肯定在A之后,因为其在同一个线程,必然按照顺序结构执行
  3. C肯定在A之后,因为错误监听是在A线程最后的view.setVisibility(View.VISIBLE)语句后开始

有了这三点,就能得出结论,起冲突的主要是B和C,而C本身并不执行方法,只是调用D而已,所以我要确保的是先B后D的执行顺序,实际是ABD的执行顺序(C可以忽略)。修改以下部分:
增加flagError 、flagB全局变量
A部分

	省略业务代码...
	flagB=false;
	flagError = false;
	view.setVisibility(View.VISIBLE);// 显示播放器

B部分

	省略业务代码...
	if(!flagError){
		videoPlay = true;// 播放标志打开
		view.start();// 开始播放
		flagB=true;
	}else{
			调用D方法
	}

C部分

	setOnErrorListener监听{
		flagError = true;
		if(flagB){
		调用D方法
		}
	}

这样修改后,如果AB先执行,因为C没有触发,flagError为false,所以flagB为true,所以C会调用D,顺序依然是ABCD,和正常情况下一样。
如果A执行后,C抢线程,flagError为true,此时B还未执行,所以flagB为False,C就不会调用D。接下来恢复中断,就变成ACB顺序,B这里因为flagError已经为true,所以会调用D,执行顺序是ACBD. 保证了ABD的先后顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值