If we develop an application that needs to play audio, we all know that the audio will be used for the MediaPlayer class, where I do not need to turn on the service, play audio in this activity, and when the activity is destroyed, the audio ends
But there is a focus that needs immediate change the current playback time
My idea is to open a thread that calculates the remaining playback time of the current audio, and if >0 uses a handler loop to send a message to change the time UI
thread tplay ; Tplay = new thread (new runnable () { @Override public void run () { int time
= (Mplay.getduration ()-mplay.getcurrentposition ())/1000; // get the time remaining for the current audio, total time-current playback length while (time>0&&mplay!=null) { // If the remaining time >0 and MediaPlayer objects exist, it will take 0.2 seconds to update the time UI try {
thread.sleep (200); time = (Mplay.getduration ()-mplay.getcurrentposition ())/1000; // Get current Time final
int finalTime = time; handler.post ( New runnable () { @Override public void run () {
topic_play_time.settext (finaltime /60+ "'" + finaltime %60); //Change UI }
}); } catch ( Interruptedexception e) {
e.printstacktrace (); } }  }});
Then the thread object, when start, is necessarily the first time to play the audio, and can only start once.
So here's the problem. When I play the audio, or pause the audio that has been played, the user may quit the activity,
And the activity was destroyed, but this activity was turned on. The child thread that changed the UI still exists, and it needs to cycle through the remaining time, but the MediaPlayer object is gone and the error is not available.
Therefore, the solution can only be to terminate the activity before the start of the child thread.
Tried several methods, and finally selected one of the simplest and most understandable methods:
That
1, set a global tag variable boolean flag = true;
2, the thread in the while loop to determine whether the flag is true, is to execute the internal code, otherwise do not execute, end loop, that is, the thread is also the end of the
Tplay = new Thread (new Runnable () {
@Override public
void Run () {
int time = (mplay.getduratio N ()-mplay.getcurrentposition ())/1000;
while (Time>0&&mplay!=null&&flag) {
}
}
});
3, destroyed in the activity
@Override
protected void OnDestroy () {
Super.ondestroy ();
Isflag=false;
}
method to change the flag, the thread will end without an error while the while condition is not set.
Key code:
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 ())/1000; while (time> 0&&mpLay!=null&&isflag) { 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); }
}); } catch (interruptedexception e) {
e.printstacktrace ();
} } }
});
initview ();
initdata (attention);    &NBSP} /** * data show * @param attention */ private void initdata (serializable attention) {   &Nbsp; entity = (Attention) attention; int nowtime
= integer.parseint (Entity.getaudiolength ()); topic_play_time.settext (nowtime/60 + "'" +
 NOWTIME%60); } /** * Initialization Control */ private void initview () { topic_play_music = (
ImageButton) findviewbyid (r.id.topic_play_music);
topic_play_music.setonclicklistener (this);    &NBSP} @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{ &nBsp; mplay.start ();
topic_play_music.setimageresource (R.mipmap.ui_detail_pause);
} }
break;
       &NBSP}  } @Override protected void ondestroy () {
super.ondestroy ();
isflag=false; try { tplAy.sleep (500); } catch (interruptedexception e) {
e.printstacktrace ();        &NBSP} if ( Mplay!=null) { mplay.stop ();
mplay.release (); }  }}
Thread update UI opened in activity, thread not finished, exiting activity, causing problem
When an activity exits, its child threads are still running, and an exception problem occurs:
Solution, using the flag logo bit in the thread
public void Run ()
{while
(Flag)
{
...
). }
}
In the Ondestory () method of the main thread, the following code is used:
Flag = false;
Try
{
threadsleep (500);//wait child thread end
handler.removemessage (...);
}