计时器在活动关闭并重新启动后不会停止

问题描述:

我有一个每秒更新一次textview的runnable计时器,当活动处于onStop(或称为后台)计时器继续运行时。我遇到的问题是,当我重新启动活动时,它会再次启动相同的计时器,因此数字会以其应有的速度提高两倍。我把它编码,这样它会在重新启动它们之前杀死两个计时器,但我相信当活动再次启动时,计时器不会被杀死。下面是我的代码示例:计时器在活动关闭并重新启动后不会停止

t.cancel(); 
    cd.cancel(); 
    t = new Timer(); 
    t.schedule(new TimerTask() { 

     @Override 
     public void run() { 
      runOnUiThread(new Runnable() { 

       public void run() { 

那只是一小部分,但它应该终止计时器(t.cancel();),然后开始一个新的,当活动停止这只是发生和然后重新启动。请帮助这个问题让我绝对疯了。

============================================== ===========

对于愿意读很多的勇敢的灵魂,这里要说的是我有问题我的整个活动:

public class PayTracker extends Activity { 
    private static double Reserve; 
    private static int Reserve1; 
    public static double money; 
    public static double counter; 
    private static int go; 
    private static int countdown; 
    public static int convert; 
    public static double HW; 
    public static double OTW; 
    public static double HPD; 
    public static double DPPS; 
    public Timer t = new Timer(); 
    public Timer cd = new Timer(); 
    public static String mcountdown = "Time till overtime"; 
    public static String mmoney = "total cash"; 
    public static String mcounter = "ticks"; 
    public static String mReserve = "building total"; 
    public static String mReserve1 = "building total 2"; 
    public static String mHW; 
    public static String mOTW; 
    public static String mHPD; 
    public static String mDPPS; 
    public static String mgo; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_pay_tracker); 
     getActionBar().setDisplayHomeAsUpEnabled(true); 
    // Receive messages from options page 
     double pHW, pOTW, pHPD; 
     Intent intent = getIntent(); 
     pHW = intent.getDoubleExtra(Options.MESSAGE_HW, 0); 
     pOTW = intent.getDoubleExtra(Options.MESSAGE_OTW, 0); 
     pHPD = intent.getDoubleExtra(Options.MESSAGE_HPD, 0); 
     if(pHW != 0){ 
      HW = pHW; 
      OTW = pOTW; 
      HPD = pHPD; 
     } 
    // Color buttons 
     Button buttonc = (Button) findViewById(R.id.clockin); 
     buttonc.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY); 
     Button buttond = (Button) findViewById(R.id.clockout); 
     buttond.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY); 

//  go = 0; 
     // Calculate pay per second 
     final double PPS = (HW/3600); 
     DPPS = (PPS/50); 
     final double OTPPS = (OTW/3600); 
     final double DOTPPS = (OTPPS/50); 
     final double HPDPS = (HPD*3600); 
     final double DHPDPS = (HPDPS*50); 
     // Display 

     final TextView t1 = (TextView) findViewById(R.id.yourpay); 
     t1.setTextColor(Color.parseColor("#008000")); 
     final TextView t2 = (TextView) this.findViewById(R.id.payper); 
     final String result2 = String.format("%.8f", OTPPS); 
     final String result = String.format("%.8f", PPS); 

     // if(go != 1){ 
     // go = 1; 
     // if(go == 1){ 
     t.cancel(); 
     cd.cancel(); 
     // go = 0; 
     // } 
     // if(go == 0){ 
     // go = 1; 
     t = new Timer(); 
     t.schedule(new TimerTask() { 

      @Override 
      public void run() { 
       runOnUiThread(new Runnable() { 

        public void run() { 
         if(DHPDPS==0){ 
          money = (DPPS+Reserve); 
          Reserve = (money); 
          String end = String.format("%1f", money); 
          t1.setText("$" + end); 
         }else if(counter > DHPDPS && DOTPPS != 0 && DHPDPS != 0){ 
          money = (DOTPPS+Reserve); 
          Reserve = (money); 
          String end = String.format("%1f", money); 
          t1.setText("$" + end); 
         } else{ 

          money = (DPPS+Reserve); 
          Reserve = (money); 
          String end = String.format("%1f", money); 
          t1.setText("$" + end); 
         } 
         counter++; 
         //if(counter == 3000) 
         // t.cancel(); 

         // Display pay per second 
         if(counter <= DHPDPS || DHPDPS == 0){ 
         t2.setText("Your pay per second is: $"+result); 
         }else{ 
          t2.setText("Your pay per second is: $"+result2); 
         } 
        } 
       }); 
      } 
     }, 20, 20); 

    // Make countdown to overtime display 

     final Intent intent1 = new Intent(this, PayTracker.class); 
    // Create the notification 
     final Notification notification = new Notification(R.drawable.ic_launcher, "Click here to check your pay!", System.currentTimeMillis()); 
     // Create an Intent for the notification to launch 
     // Create a PendingIntent for the associated Intent 
     final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent1, 0); 
     cd = new Timer(); 
     final TextView count = (TextView) findViewById(R.id.countdown); 
     convert = (int)HPDPS; 
     cd.schedule(new TimerTask() { 
      @Override 
      public void run() { 
       runOnUiThread(new Runnable() { 
        public void run(){ 
         countdown = (convert - Reserve1); 
         int hours = (countdown/3600); 
         if(OTPPS != 0 && HPDPS != 0){ 
           count.setText("Seconds Remaining to Overtime: " + countdown + "\nAbout " + hours + " Hours"); 
           Reserve1++; 
          } 

         // Set the notification's details 
         final String end = String.format("%.6f", money); 
         notification.setLatestEventInfo(getApplicationContext(), "Your Current Pay:", "$"+end, pendingIntent); 
         // Submit the notification to the system 
         ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(0, notification); 
        } 
       }); 
      } 

     }, 1000, 1000); 
     // } 
     // } 


     final Button b = (Button) findViewById(R.id.clockout); 
     b.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 
       if(go == 1) 
        go = 0; 
       if (t != null){ 
        t.cancel(); 
        cd.cancel(); 
       } 
       } 
     }); 

    } 

    public void onRestoreInstanceState(Bundle savedInstanceState) { 
     // Always call the superclass so it can restore the view hierarchy 
     super.onRestoreInstanceState(savedInstanceState); 
      // Restore value of members from saved state 
      countdown = savedInstanceState.getInt(mcountdown); 
      Reserve = savedInstanceState.getInt(mReserve); 
      money = savedInstanceState.getInt(mmoney); 
      counter = savedInstanceState.getInt(mcounter); 
      Reserve1 = savedInstanceState.getInt(mReserve1); 
      HW = savedInstanceState.getInt(mHW); 
      OTW = savedInstanceState.getInt(mOTW); 
      HPD = savedInstanceState.getInt(mHPD); 
      DPPS = savedInstanceState.getInt(mDPPS); 
      go = savedInstanceState.getInt(mgo); 
    } 

    @Override 
    public void onStart(){ 
     super.onStart(); 


    } 



    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_pay_tracker, menu); 
     return true; 
    } 


    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case android.R.id.home: 
       NavUtils.navigateUpFromSameTask(this); 
       return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    public void sendMessage(View view) { 
     // Calculate pay per second 
     final double PPS = (HW/3600); 
     DPPS = (PPS/50); 
     final double OTPPS = (OTW/3600); 
     final double DOTPPS = (OTPPS/50); 
     final double HPDPS = (HPD*3600); 
     final double DHPDPS = (HPDPS*50); 
     // Display 

     final TextView t1 = (TextView) findViewById(R.id.yourpay); 
     t1.setTextColor(Color.parseColor("#008000")); 
     final TextView t2 = (TextView) this.findViewById(R.id.payper); 
     final String result2 = String.format("%.8f", OTPPS); 
     final String result = String.format("%.8f", PPS); 

     //if(go != 1){ 
     // go = 1; 
      t.cancel(); 
      cd.cancel(); 
     t = new Timer(); 
     t.schedule(new TimerTask() { 

      @Override 
      public void run() { 
       runOnUiThread(new Runnable() { 

        public void run() { 
         if(DHPDPS==0){ 
          money = (DPPS+Reserve); 
          Reserve = (money); 
          String end = String.format("%1f", money); 
          t1.setText("$" + end); 
         }else if(counter > DHPDPS && DOTPPS != 0 && DHPDPS != 0){ 
          money = (DOTPPS+Reserve); 
          Reserve = (money); 
          String end = String.format("%1f", money); 
          t1.setText("$" + end); 
         } else{ 

          money = (DPPS+Reserve); 
          Reserve = (money); 
          String end = String.format("%1f", money); 
          t1.setText("$" + end); 
         } 
         counter++; 
         if(counter == 3000) 
          t.cancel(); 

         // Display pay per second 
         if(counter <= DHPDPS || DHPDPS == 0){ 
         t2.setText("Your pay per second is: $"+result); 
         }else{ 
          t2.setText("Your pay per second is: $"+result2); 
         } 
        } 
       }); 
      } 
     }, 20, 20); 

    // Make countdown to overtime display 

     final Intent intent1 = new Intent(this, PayTracker.class); 
    // Create the notification 
     final Notification notification = new Notification(R.drawable.ic_launcher, "Click here to check your pay!", System.currentTimeMillis()); 
     // Create an Intent for the notification to launch 
     // Create a PendingIntent for the associated Intent 
     final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent1, 0); 
     cd = new Timer(); 
     final TextView count = (TextView) findViewById(R.id.countdown); 
     convert = (int)HPDPS; 
     cd.schedule(new TimerTask() { 
      @Override 
      public void run() { 
       runOnUiThread(new Runnable() { 
        public void run(){ 
         countdown = (convert - Reserve1); 
         int hours = (countdown/3600); 
         if(OTPPS != 0 && HPDPS != 0){ 
           count.setText("Seconds Remaining to Overtime: " + countdown + "\nAbout " + hours + " Hours"); 
           Reserve1++; 
          } 

         // Set the notification's details 
         final String end = String.format("%.6f", money); 
         notification.setLatestEventInfo(getApplicationContext(), "Your Current Pay:", "$"+end, pendingIntent); 
         // Submit the notification to the system 
         ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(0, notification); 
        } 
       }); 
      } 

     }, 1000, 1000); 

     //} 
    } 



    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState) { 
     // Save the user's current game state 
     savedInstanceState.putInt(mcountdown, countdown); 
     savedInstanceState.putDouble(mReserve, Reserve); 
     savedInstanceState.putDouble(mmoney, money); 
     savedInstanceState.putDouble(mcounter, counter); 
     savedInstanceState.putDouble(mReserve1, Reserve1); 
     savedInstanceState.putDouble(mHW, HW); 
     savedInstanceState.putDouble(mOTW, OTW); 
     savedInstanceState.putDouble(mHPD, HPD); 
     savedInstanceState.putDouble(mDPPS, DPPS); 
     savedInstanceState.putInt(mgo, go); 

     // Always call the superclass so it can save the view hierarchy state 
     super.onSaveInstanceState(savedInstanceState); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

     if(t != null) 
      t.cancel(); 
     if(cd != null) 
      cd.cancel(); 
    } 

} 
+0

运行中是否存在while循环? – 2012-08-07 20:23:34

+0

@Andi Jay no theres不是 – Hockeyman271 2012-08-07 20:24:49

+0

你能不能在'onStop()'中调用'Timer.cancel()'? – 2012-08-07 20:25:04

这是获得一种方式在那附近。

static Timer mTimer = null; 

onCreate() { 
    if (mTimer == null) 
     mTimer = new Timer(); 
    } else { 
     // You shouldn't have to do nothing because your timer should be running 
    } 
} 

请注意,这里一般有几个问题。静态基本上只是说创建该对象的一个​​实例。作为副作用,它也试图回收相同的内存地址。无论哪种方式,一旦你的应用程序在后台,它可以在任何时候由系统清理,所以你不能保证让你的定时器回来。还有其他一些方法可以解决这个问题,但这个问题超出了范围。

+0

您能解释一些其他方式来解决在后台有计时器吗?我知道它不是针对这个问题,但它会帮助我很大程度上与我的项目,即时通讯新的android编程,所以即时通讯仍然试图学习 – Hockeyman271 2012-08-07 20:50:39

+0

张贴的问题,并发送给我的链接 – 2012-08-07 20:51:41

+0

我会尽快我有时间,但我试过这种方法和它的工作原理,唯一的问题是现在我的用户界面不会在活动重新启动时更新?我可以在我的通知栏中看到计时器仍在运行,但用户界面不会填充 – Hockeyman271 2012-08-07 20:59:33