0

我有一个可运行的计时器,它每秒更新一个文本视图,当活动处于 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();   
    }

}
4

1 回答 1

1

这是解决这个问题的一种方法。

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
    }
}

请注意,这里通常存在几个问题。静态基本上是说只是创建该对象的一个​​实例。作为副作用,它还尝试回收相同的内存地址。无论哪种方式,一旦您的应用程序处于后台,系统就可以随时清理它,因此您不能保证可以恢复您的计时器。还有很多其他方法可以解决这个问题,但这超出了这个问题的范围。

于 2012-08-07T20:46:59.747 回答