Android - 如何在后台运行多个计时器

时间:2015-07-17 02:57:36

标签: java android timer

我目前正在构建一个在wifi扬声器上播放音乐的应用。该应用程序可以连接到多个扬声器,每个扬声器播放不同的音乐。

由于接收扬声器发送到应用程序的歌曲播放进度经常丢失,我必须为正在播放音乐的每个扬声器运行一个计时器,以便持续跟踪歌曲进度。因此,每次收到歌曲进度时,我都会更新计时器,然后计时器将从更新的歌曲进度开始计数。

这是运行计时器的代码。

public class SongTimer
{
     Timer mTimer;
     int count;
     long duration;
     int groupAddress;
     SongTimerListener listener;

     boolean timer;

     private Handler mHandler = new Handler();

     public interface SongTimerListener
     {
         public void onPositionCounted(int position);
         public void onFinishCounting();
     }

     public SongTimer(int position, long duration, int groupAddress, SongTimerListener listener)
     {
         this.listener = listener;
         this.count = position;
         this.duration = duration;
         this.groupAddress = groupAddress;

         timer = true;
     }

     public void startTimer() 
     {      
         mTimer = new Timer();
         mTimer.schedule(new TimerTask()
         {
             @Override  
             public void run()
             {
                 if (timer)
                 {
                    if(count<=(duration/1000))
                    {
                        mHandler.post(new Runnable()
                        {
                            public void run(){

                                if (DataHolder.PlayProgress.containsKey(DataHolder.tSpeaker.mAddress))
                                {
                                    long progress = DataHolder.PlayProgress.get(DataHolder.tSpeaker.mAddress);
                                    count=(int)progress;
                                }
                            }
                         });

                     }

                    else
                    {
                        mHandler.post(new Runnable()
                        {
                            public void run()
                            {
                                count = 0; 
                            }
                        });
                    }
                }

                else
                {
                    mHandler.post(new Runnable()
                    {
                        public void run()
                        {
                            mTimer.cancel();
                            mTimer = null;

                            if(SongTimer.this.listener != null)
                            {
                                SongTimer.this.listener.onFinishCounting();
                            }
                        }
                    });
                }

                count++;

                if(SongTimer.this.listener != null)
                {
                    SongTimer.this.listener.onPositionCounted(count);
                }
            }

         }, 1000, 1000);
    } 

    public void stopTimer()
    {
        timer = false;
        DataHolder.PlayProgress.put(this.groupAddress, (long)count);
    }
}

用户选择扬声器,然后当用户使用扬声器播放音乐时,将启动一个计时器。当用户切换到另一个扬声器并用它播放一首歌时,将再次启动一个新的计时器。所有已启动的计时器都将使用 groupAddress 作为对象的计时器存储在HashMap中。

当用户点击暂停时,将从HashMap获取计时器然后终止计时器,但会记住计算的最后一个位置。

当用户点击恢复时,将再次开始计时(新的计时器()),然后从存储的最后一个位置开始计数。

问题出现了:

当多个计时器开始运行时,它们运行正常。但是当用户点击暂停时,将从HashMap中获取一个计时器,然后终止它。但不幸的是,所有计时器都在同一时间终止。我检查了Log的定时器的对象ID,它们都是不同的。所以我不明白这里有什么问题。

请帮忙。非常感谢!

1 个答案:

答案 0 :(得分:1)

尝试这个

public class SongTimer{
 int count;
 long duration;
 int groupAddress;
 SongTimerListener listener;
 boolean timer,run;
 View user; //the view who this is going to be attached to

 public interface SongTimerListener {
     public void onPositionCounted(int position);
     public void onFinishCounting();
 }
 //your constructor
 public SongTimer(int position, long duration, int groupAddress,
           SongTimerListener listener, View viewToAttach){  //added new parameter
     this.listener = listener;
     this.count = position;
     this.duration = duration;
     this.groupAddress = groupAddress;
     timer = run = true;
     user = viewToAttach;
     new Thread(new Runnable() { // your timer 

        @Override
        public void run() {
            while(run){
              if(!timer)
                 continue;
               //now add your implementation here, (its too late here)
       //put your code that you already have here, but minor changes
       //if you need to call a Ui method use the user.post(runnable); it
       // the same as handler.post(runnable), also with this you have 
      // reference to your view to which you want to alter, so all you
      // to do is do what you want to do easily without actually needing
     // your interface call. and all Views that they rely on the music
     //mechanism that you talked about will each have an instance of this
    //class. your pausing mechanism has already being implemented so 
   //maintain your old pausing mechanism. Also if you are done and want 
   // totally stop the thread or kill this class set the boolean run 
   //variable to false.

        }
    }).start();
 }

希望有所帮助