Таймер не останавливается после того, как действие было закрыто и перезапущено

У меня есть работающий таймер, который обновляет текстовое представление каждую секунду, когда активность находится на останове (или вызывается в фоновом режиме), таймер продолжает работать. Проблема, с которой я столкнулся, заключается в том, что, когда я перезапускаю упражнение, он снова запускает тот же таймер, поэтому числа увеличиваются вдвое быстрее, чем следовало бы. Я запрограммировал его так, чтобы он убивал оба таймера, прежде чем перезапустить их, но я верю, что при повторном запуске действия таймеры не убиваются. Вот пример моего кода:

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

}

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

Обратите внимание, что здесь есть несколько проблем. Статика в основном говорит только о создании одного экземпляра этого объекта. В качестве побочного эффекта он также пытается восстановить тот же адрес памяти. В любом случае, если ваше приложение находится в фоновом режиме, оно может быть очищено системой в любое время, поэтому вы не гарантированно вернете свой таймер. Есть множество других способов обойти это, но это выходит за рамки этого вопроса.

Другие вопросы по тегам