分享

关于Activity销毁,而绘制UI的子线程未销毁出现的问题

 quasiceo 2016-07-25

关于Activity销毁,而绘制UI的子线程未销毁出现的问题

项目总结

---------------------------------------------------------------------------------------------------------

有一个功能模块,需要播放音频,画一个简单的界面

一个例子:

我们都知道播放音频要用到MediaPlayer类,我这里,不需要开启Service,就在本Activity播放音频,当Activity销毁的时候,音频便结束

但是有一个重点,需要即时的变化当前播放的时间

我的思路是,开启一个线程,计算当前音频的剩余播放时间,如果>0 则用Handler循环发送一个消息来更改时间UI

复制代码
Thread tPlay ;
tPlay = new Thread(new Runnable() {
            @Override
            public void run() {
                int time = (mPlay.getDuration()-mPlay.getCurrentPosition())/1000;  // 获得当前的音频的剩余时间,总时长-当前播放时长
                while(time>0&&mPlay!=null) {                                       // 如果剩余时间>0 并且MediaPlayer对象存在,就需要没0.2秒更新一下时间UI
                    try {
                        Thread.sleep(200);
                        time = (mPlay.getDuration()-mPlay.getCurrentPosition())/1000; //获得当前时间
                        final int finalTime = time;
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                topic_play_time.setText(finalTime /60+"'"+ finalTime %60); //更改UI
                            }
                        });
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
复制代码

 

然后有线程对象了,什么时候start呢,必然是在第一次播放音频的时候,而且只能start一次。

 

那么问题来了。当我播放音频的时候,或者暂停已经播放一段的音频的时候,用户可能会退出Activity ,

而Activity销毁了,但是这个Activity开启的计算时间更改UI的子线程还存在,它还需要循环计算剩余时间,但是MediaPlayer对象没了,就报错了。

 

所以,解决方法只能是销毁Activity之前结束这个Activity开启的子线程。

试过几种方法,最后选定了一个最简单,最易理解的方法:

1、设置一个全局标记变量boolean flag = true;

2、线程中while 循环判断 flag 是否为true,是则执行内部代码,否则不执行,结束循环了,即线程也随之结束了

复制代码
tPlay = new Thread(new Runnable() {
            @Override
            public void run() {
                int time = (mPlay.getDuration()-mPlay.getCurrentPosition())/1000;
                while(time>0&&mPlay!=null&&flag) {
                }
            }
        });
复制代码

 

3、在Activity销毁的

@Override
protected void onDestroy() {
    super.onDestroy();
    isflag=false;
}

 

方法中更改flag,那么线程中while条件则不成立,线程就结束了,也不会再报错了。

 

贴一下关键代码:

关键代码

 

posted @ 2015-11-12 20:42 听着music睡 阅读(499) 评论(10) 编辑 收藏
评论列表
  
#1楼 2015-11-12 21:04 KillU  
为什么进程都推出了 线成还在?
  
#2楼[楼主] 2015-11-12 21:34 听着music睡  
@ KillU
实际上线程还是存在的,可以做个测试,开启一个子线程 while 死循环 来设置一个TextView 文本信息,看看退出进程后,是不是会报错
  
#3楼 2015-11-12 22:10 奔跑的蜗牛丶  
播放视屏之前 VideoView是不是黑的?楼主有碰到这种情况吗?
  
#4楼[楼主] 2015-11-12 22:12 听着music睡  
@ 奔跑的蜗牛丶
是播放界面出来之前黑的闪一下,还是黑到播放界面出来,还是你视频播放自动到转横屏并闪黑一下
  
#5楼 2015-11-12 22:13 奔跑的蜗牛丶  
@ 听着music睡
播放界面出来之后,没有播放视频一直是黑的。
  
#6楼[楼主] 2015-11-13 08:38 听着music睡  
@ 奔跑的蜗牛丶
那就是代码出问题了,看下VideoView使用步骤,一般没有这种情况的。
  
#7楼 2015-11-17 16:28 掌握当下  
没必要开线程。。。
  
#8楼[楼主] 2015-11-17 21:18 听着music睡  
@ 掌握当下
请教下不开线程的情况下该怎么处理,我的思维这个情况一般要开线程。。。
  
#9楼 2015-11-18 14:33 掌握当下  
更新UI本质上不在子线程上操作,UI操作必须在UI主线程中进行~可以用handler或者postdelay。。。方法很多~你的子线程中的post方法不就是为了把UI更新放到主线程中操作吗~
  
#10楼[楼主] 2015-11-18 19:01 听着music睡  
@ 掌握当下
说的对,忽视这点了

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多