因为一个业务场景需要用到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部分
视频的关闭以及其他操作的业务代码
结合业务代码,再来看问题
- C的作用其实主要是在出错时调用D
- B肯定在A之后,因为其在同一个线程,必然按照顺序结构执行
- 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的先后顺序。