Solution for the child thread that paints the UI without destroying the activity in Android

Source: Internet
Author: User
Tags current time sleep

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 ();             }          }    &nbsp}});


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}    &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 ();         }    &nbsp}}



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 (...);
}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.