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

标签 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);
    }
}

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

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

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

问题来了:

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

请帮忙。非常感谢!

最佳答案

试试这个

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

希望对你有帮助

关于java - Android - 如何在后台运行多个计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31467745/

相关文章:

java - apache mina 中的死 session

java - 使用 GAE/J URLFetchServiceFactory.getURLFetchService() 的 JUnit 代码测试

java - 如何水平添加TextView?

一个定时器上只能由一个 channel 提供 pwm 信号吗?

java - 如何在 java 2d 射击游戏中将计时器设置为 1 分钟?

c# - 倒计时文本字段在倒计时期间未更新

Java动态、静态转换

javascript - Phonegap - 动态邮件附件

Android图像调整大小错误

java - 等待上一个函数执行完毕