关于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())/; // 获得当前的音频的剩余时间,总时长-当前播放时长
while(time>&&mPlay!=null) { // 如果剩余时间>0 并且MediaPlayer对象存在,就需要没0.2秒更新一下时间UI
try {
Thread.sleep();
time = (mPlay.getDuration()-mPlay.getCurrentPosition())/; //获得当前时间
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())/;
while(time>&&mPlay!=null&&flag) {
}
}
});
3、在Activity销毁的
@Override
protected void onDestroy() {
super.onDestroy();
isflag=false;
}
方法中更改flag,那么线程中while条件则不成立,线程就结束了,也不会再报错了。
贴一下关键代码:
public class TopicDetailActivity extends Activity implements View.OnClickListener {
private ImageButton topic_play_music;
private Attention entity;
private boolean isflag= true;
private MediaPlayer mPlay;
private Thread tPlay;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_topic_detail);
Intent intent = getIntent();
Serializable attention = intent.getSerializableExtra("attention");
tPlay = new Thread(new Runnable() {
@Override
public void run() {
int time = (mPlay.getDuration()-mPlay.getCurrentPosition())/;
while(time>&&mPlay!=null&&isflag) {
try {
Thread.sleep();
time = (mPlay.getDuration()-mPlay.getCurrentPosition())/;
final int finalTime = time;
handler.post(new Runnable() {
@Override
public void run() {
topic_play_time.setText(finalTime /+"'"+ finalTime %);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
initView();
initData(attention);
}
/**
* 数据展示
* @param attention
*/
private void initData(Serializable attention) {
entity = (Attention) attention;
int nowTime = Integer.parseInt(entity.getAudiolength());
topic_play_time.setText(nowTime/ + "'" + nowTime%);
}
/**
* 初始化控件
*/
private void initView() {
topic_play_music = (ImageButton) findViewById(R.id.topic_play_music);
topic_play_music.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.topic_play_music:
if(mPlay==null){
mPlay = new MediaPlayer();
mPlay.reset();
try {
mPlay.setDataSource("http://imagecdn.xunjimap.com/image/" + entity.getAudiourl());
mPlay.prepare();
topic_play_music.setImageResource(R.mipmap.ui_detail_pause);
mPlay.start();
tPlay.start();
} catch (IOException e) {
e.printStackTrace();
}
}else{
if (mPlay.isPlaying()){
mPlay.pause();
topic_play_music.setImageResource(R.mipmap.ui_detail_play);
}else{
mPlay.start();
topic_play_music.setImageResource(R.mipmap.ui_detail_pause);
}
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
isflag=false;
try {
tPlay.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mPlay!=null){
mPlay.stop();
mPlay.release();
}
}
}
关键代码
关键代码
关于Activity销毁,而绘制UI的子线程未销毁出现的问题的更多相关文章
- android 不能在子线程中更新ui的讨论和分析
问题描写叙述 做过android开发基本都遇见过 ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是仅仅能在主线程中更改 ui.子线程要 ...
- Android 子线程无法刷新UI界面
问题:在Android开发中,子线程无法直接更改UI界面视图的刷新 这个时候 Handler 起到了至关重要的作用. 简单来说 , Handler就是用来传递消息的. Handler可以当成子线程与主 ...
- Python_线程、线程效率测试、数据隔离测试、主线程和子线程
0.进程中的概念 三状态:就绪.运行.阻塞 就绪(Ready):当进程已分配到除CPU以外的所有必要资源,只要获得处理机便可立即执行,这时的进程状态成为就绪状态. 执行/运行(Running)状态:当 ...
- Java并发编程原理与实战六:主线程等待子线程解决方案
本文将研究的是主线程等待所有子线程执行完成之后再继续往下执行的解决方案 public class TestThread extends Thread { public void run() { Sys ...
- C#定时检測子线程是否已经完毕
C#定时检測子线程是否已经完毕 class Program { static void Main(string[] args) { //主线程中启动一个支线程,运行doSomething这种一个方法. ...
- python3 结束子线程
最近公司内部网络经常出问题,奇慢无比,导致人脸检测程序在下载图片时经常卡住,为了不影响数据的核对, 决定在网络不佳图片下载超时后放弃下载,继续执行后续程序. 于是整理出解决思路如下: 1.在线程中完成 ...
- (转)Android在子线程中更新Activity中UI的方法
转:http://blog.sina.com.cn/s/blog_3fe961ae0100mvc5.html 在Android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处 ...
- Android 子线程更新UI 异常
众所周知,Android是不可以在子线程中直接更新UI的,需要借助Handler或者View.post(Runnable runnable)或者runOnUIThread(Runnable runna ...
- Android多线程之(一)View.post()源码分析——在子线程中更新UI
提起View.post(),相信不少童鞋一点都不陌生,它用得最多的有两个功能,使用简便而且实用: 1)在子线程中更新UI.从子线程中切换到主线程更新UI,不需要额外new一个Handler实例来实现. ...
随机推荐
- nginx url自动加斜杠的问题
nginx url自动加斜杠问题及301重定向 时间:2016-02-04 15:14:28来源:网络 导读:nginx url自动加斜杠问题及301重定向,URL指向一个目录并且在最后没有包含斜杠, ...
- Oracle---.oracle函数
数值型函数: 绝对值: ABS(x) [功能]返回x的绝对值 [参数]x,数字型表达式 [返回]数字 [示例] select abs(100),abs(-100) from dual;-------- ...
- 享元模式及C++实现
享元模式(flyweight) flyweight是轻量级的意思,中文这边翻译成享元,更容易让人理解一些. 享元模式是为了应对大量细粒度对象重复的问题.程序中存在大量细粒度的对象,每次要使用时都必须创 ...
- 各种Camera,总有一款适合你(二)
在实际的项目开发中,一般需要程序抽象出一些在几何意义上有明确意义的参数,这样方便策划或美术在自己的机器上进行调试. 下面是一个可变参的地下城摄像机的简单实现: // 第三人称摄像机,平移和旋转会同时进 ...
- 主机访问虚拟机中linux上的web服务
环境:主机windows xp 虚拟机centos 6.4 [root@localhost /]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT[root ...
- window xp Apache与Tomcat集群配置--转载
转载地址:http://www.cnblogs.com/obullxl/archive/2011/06/09/apache-tomcat-cluster-config.html 一. 环境说明 Win ...
- GitHub上那些值得一试的JAVA开源库
作为一名程序员,你几乎每天都会使用到GitHub上的那些著名Java第三方库,比如Apache Commons,Spring,Hibernate等等.除了这些,你可能还会fork或Star一些其他的开 ...
- iOS-UIScrollView-图片缩放
一. 实现功能 两个手指捏合,可以放大或者缩小图片. 二.原理说明 1. 实现缩放功能的四个步骤 (1) 让控制器遵守代理协议 (2) 让scrollView设置代理 self (3) 调用代理方法, ...
- Spring应用教程-1
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) Spring是Web框架,是容器框架,用于配置bean,并维护bean之间的关系的框架. 1. Spring在整 ...
- HTML的学习
PS:最近已经进入实验室了,已经算是正式的成为其中的核心成员了,虽然自己学习的并不多.但是 相信自己通过努力能够走的越来越好.条件还是蛮不错的.这次给了一个关于WEB的项目,自己的还是 没有学完JAV ...