关于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实例来实现. ...
随机推荐
- 【转】How to resolve ORA-19706 error when select from dblink
文章转自:http://www.dbform.com/html/2012/1846.html
- struts2 hello world
注意:仅需要如下这些jar包,否则启动时会出错 commons-lang3-3.2.jar commons-logging-1.1.3.jarcommons-logging-api-1.1.jarfr ...
- SNF开发平台WinForm之六-上传下载组件使用-SNF快速开发平台3.3-Spring.Net.Framework
6.1运行效果: 6.2开发实现: 1.先在要使用的项目进行引用,SNF.WinForm.Attachments.dll文件. 2.在工具箱内新建选项卡->选择项,浏览找到文件SNF.WinFo ...
- 【转】为什么很多看起来不是很复杂的网站,比如 Facebook、淘宝,都需要大量顶尖高手来开发?
先说你看到的页面上,最重要的几个:[搜索商品]——这个功能,如果你有几千条商品,完全可以用select * from tableXX where title like %XX%这样的操作来搞定.但是— ...
- UWP开发入门(十五)——在FlipView中通过手势操作图片
本篇的最终目的,是模拟系统的照片APP可以左右滑动,缩放图片的操作.在实现的过程中,我们会逐步分析UWP编写UI的一些思路和技巧. 首先我们先实现一个横向的可以浏览图片的功能,也是大部分APP中的实现 ...
- ASP.NET跨服务器上传文件的相关解决方案
第一种:通过FTP来上传文件 首先,在另外一台服务器上设置好FTP服务,并创建好允许上传的用户和密码,然后,在ASP.NET里就可以直接将文件上传到这台 FTP 服务器上了.代码如下: <%@ ...
- SQL语句技巧之去除重复行
去除表中重复行数据,可能大家立马就想到的是用DISINTCT关键字,但DISINTCT只能是去除表中所有列都相同的行,若碰到需要去除表中多个字段重复的行(即:部份相同,部份不相同),那么该如何做呢?我 ...
- ASP.NET身份验证
Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验 证用的最多,也最灵活. Forms 验证方式对基于用户的验证 ...
- java的poi技术下载Excel模板上传Excel读取Excel中内容(SSM框架)
使用到的jar包 JSP: client.jsp <%@ page language="java" contentType="text/html; charset= ...
- 360 webscan中防注入跨站攻击的核心
//get拦截规则 $getfilter = "\\<.+javascript:window\\[.{1}\\\\x|<.*=(&#\\d+?;?)+?>|< ...