Почему CountDownTimer не запускается OnTick, когда это необходимо?

#java #android #countdowntimer

#java #Android #countdowntimer

Вопрос:

Я везде искал ответ на эту дилемму. Таймер обратного отсчета (bsCountDownTimer) не запускается, когда это необходимо. Когда я нажимаю кнопку, предполагается, что она запускает OnTick(), правильно? Однако, только после того, как я перейду к другому действию и перейду назад с помощью кнопки ВВЕРХ, или выхожу из приложения или уничтожаю его и перезапускаю, OnTick () начинает обновлять текст и отправлять информацию в LogCat, как это указано.

Я думаю, что эта проблема относится исключительно к подклассу CDT, onBsButtonClick(), onCreate() или, возможно, к onResume() / onPause().

Вот часть исходного кода.

 public class HomeActivity extends Activity {

    @SuppressLint("NewApi") @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);

        if(bsTimeStamp!=0){bsIsRunning=true;}
        if(bsTimeStamp==0){bsIsRunning=false;}


        lastFed=(TextView)findViewById(R.id.lastFedTextView);
        feedAt=(TextView)findViewById(R.id.feedAtTextView);
        daysText = (EditText)findViewById(R.id.editTextDays);
        hoursText = (EditText)findViewById(R.id.editTextHours);
        minutesText = (EditText)findViewById(R.id.editTextMinutes);
        daysText.setText("");
        hoursText.setText("");
        minutesText.setText("");


        // get timeStamp and boolean from onFeedButtonClick() START
        final SharedPreferences prefs = this.getPreferences(Context.MODE_PRIVATE);
        feedClickTimeStamp = prefs.getLong("savedOnFeedClick", placeholder);
        bsTimeStamp = prefs.getLong("savedOnBsClick", bsProgress);
        bsPlaceholder = prefs.getLong("saved placeholder", bsPlaceholder);
        bsIsRunning = prefs.getBoolean("bs is running", bsIsRunning);
        progressbs = Long.toString(bsProgress);
        placeholderbs = Long.toString(bsPlaceholder);
        timestampbs = Long.toString(bsTimeStamp);

        timestamp = Long.toString(feedClickTimeStamp);
        LAST_FED = prefs.getString("lastFed", LAST_FED);
        FEED_AT = prefs.getString("feedAt", FEED_AT);
        feedAt.setText("Feed at: "   FEED_AT);
        lastFed.setText("Last fed at: "   LAST_FED);
        // get timeStamp and boolean from onFeedButtonClick() END


        DateTime date = new DateTime();
        long currentTime = date.getMillis();



        Long bsDiffInMillis;
            if(bsIsRunning=false) {
                bsDiffInMillis = 0L;
            }
            else {
                bsDiffInMillis = currentTime - bsTimeStamp;
                bsPlaceholder -= bsDiffInMillis;
            }


            Integer bsDiffInt = Integer.valueOf(bsDiffInMillis.intValue());
            int roundedDiff = (bsDiffInt   500) / 1000 * 1000;


        j  = roundedDiff - 2000;


// BS PROGRESS BAR START

        bsProgressBar = (ProgressBar)findViewById(R.id.bsProgressBar);
        bsProgressBar.setProgress(j);

        Long bsPlaceholderLong = bsPlaceholder;
        final Integer setMax = Integer.valueOf(bsPlaceholderLong.intValue());

        bsProgressBar.setMax(setMax);
        setProgressBarVisibility(true);   

        if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB){
            bsProgressBar.setRotation(180);
        } else{
            // FIND A WAY TO ROTATE PROGRESSBAR BEFORE API 11 (3.0)
        }

        timeDisplayBs=(TextView)findViewById(R.id.bs_countdown);        ((TextView)findViewById(R.id.bs_countdown)).setText(convertMillisForCrafting(bsPlaceholder-ji));

        millisInFuture = bsPlaceholder;

        bsCountDownTimer = new CDT(millisInFuture, countDownInterval);


//  START BS BUTTON LISTENER //         
            final Button startBsBtn = (Button) findViewById(R.id.bsButton);  
            startBsBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onBsButtonClick(view);
                } //close onClick

            }); //close onClickListener
//  END BS BUTTON LISTENER //       

        if (savedInstanceState != null) {} else {}
    }// onCreate END 


    @Override
    protected void onPause() {
        super.onPause();
        bsCountDownTimer.cancel();
    }

    @SuppressLint("NewApi") @Override
    protected void onResume() {
        super.onResume();



        SharedPreferences prefs = this.getPreferences(Context.MODE_PRIVATE);
        bsIsRunning = prefs.getBoolean("bs is running", bsIsRunning);


        if(feedClickTimeStamp>0){
            mountCountDownTimer.start();
        }
        if(bsIsRunning==true) {

            bsCountDownTimer.start();
            bsIsRunning=true;
            SharedPreferences.Editor editor = prefs.edit();
            editor.putBoolean("bs is running", bsIsRunning).commit();
        }
        if(bsIsRunning==false){
            bsIsRunning=false;
            String progressBarTitleBs = "blacksmithing research";
            timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
            timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));
            SharedPreferences.Editor editor = prefs.edit();
            editor.putBoolean("bs is running", bsIsRunning).commit();
        }
    }

    public class CDT extends CountDownTimer {

        public CDT(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
            SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
            millisInFuture = prefs.getLong("saved placeholder", bsPlaceholder);
            timeDisplayBs=(TextView)findViewById(R.id.bs_countdown);
        }

        @Override
        public void onTick(long millisInFuture) {
            Log.v("bsTimer", "Tick of Progress "   ji   " "   millisInFuture);
            ji =1;
            j =1000;
            bsProgressBar.setProgress(j);

            timeDisplayBs.setText(convertMillisForCrafting(millisInFuture-ji));
        }

        @Override
        public void onFinish() {
            bsCountDownTimer.cancel();
            j=0;
            ji=0;
            bsPlaceholder = 0;
            bsTimeStamp = 0;
            bsProgressBar.setProgress(0);
            String progressBarTitleBs = "blacksmithing research";
            timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
            timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));
        }

    }


        public void onBsButtonClick(View view) {

            final SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
            bsTimeStamp = prefs.getLong("savedOnBsClick", bsProgress);
            bsPlaceholder = prefs.getLong("saved placeholder", bsPlaceholder);
            bsIsRunning = prefs.getBoolean("bs is running", bsIsRunning);

            EditText daysText = (EditText)findViewById(R.id.editTextDays);
            EditText hoursText = (EditText)findViewById(R.id.editTextHours);
            EditText minutesText = (EditText)findViewById(R.id.editTextMinutes);
            int daysPh;
            int hoursPh;
            int minutesPh;
            String daysStr = daysText.getText().toString();
            String hoursStr = hoursText.getText().toString();
            String minutesStr = minutesText.getText().toString();




            if (daysStr.matches("") amp;amp; hoursStr.matches("") amp;amp; minutesStr.matches("")) {
                Toast.makeText(this, "You did not enter DAYS, HOURS, or MINUTES.", Toast.LENGTH_LONG).show();
                return;
            }

            if(bsIsRunning==false){

                bsPlaceholder = 0;
                bsTimeStamp = 0;
                bsIsRunning=true;
                j=0;
                bsProgressBar.setProgress(0);

                Long bsPlaceholderLong = bsPlaceholder;
                final Integer setMax = Integer.valueOf(bsPlaceholderLong.intValue());

                bsProgressBar.setMax(setMax);

                if(daysText.getText().toString().equals("")){
                    daysText.setText("0");
                }
                if(hoursText.getText().toString().equals("")){
                    hoursText.setText("0");
                }
                if(minutesText.getText().toString().equals("")){
                    minutesText.setText("0");
                }


                daysPh = Integer.parseInt(daysText.getText().toString());
                hoursPh = Integer.parseInt(hoursText.getText().toString());
                minutesPh = Integer.parseInt(minutesText.getText().toString());
                daysText.setText("");
                hoursText.setText("");
                minutesText.setText("");

                SharedPreferences.Editor editor = prefs.edit();
                bsPlaceholder = getMillisForCrafting(daysPh, hoursPh, minutesPh);
                millisInFuture = bsPlaceholder;                         //VITAL
                DateTime dt = new DateTime();
                bsProgress = dt.getMillis();

                editor.putBoolean("bs is running", bsIsRunning).commit();
                editor.putLong("savedOnBsClick", bsProgress).commit();
                editor.putLong("saved placeholder", bsPlaceholder).commit();



                bsCountDownTimer.start();
            } //close if bsIsRunning==false

            else if(bsIsRunning==true){
                view.invalidate();
                new AlertDialog.Builder(HomeActivity.this)
                .setTitle("New Blacksmithing Research Timer? (erases current)")
                .setMessage("Are you sure you want to start a new timer? n(Current timer will be erased.)")
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                            bsPlaceholder = 0;
                            bsTimeStamp = 0;
                            bsCountDownTimer.cancel();
                            bsIsRunning=true;
                            j=0;
                            bsProgressBar.setProgress(0);
                            String progressBarTitleBs = "blacksmithing research";
                            timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
                            timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));

                            EditText daysText = (EditText)findViewById(R.id.editTextDays);
                            EditText hoursText = (EditText)findViewById(R.id.editTextHours);
                            EditText minutesText = (EditText)findViewById(R.id.editTextMinutes);



                            if(daysText.getText().toString().equals("")){
                                daysText.setText("0");
                            }
                            if(hoursText.getText().toString().equals("")){
                                hoursText.setText("0");
                            }
                            if(minutesText.getText().toString().equals("")){
                                minutesText.setText("0");
                            }

                            int daysPh = Integer.parseInt(daysText.getText().toString());
                            int hoursPh = Integer.parseInt(hoursText.getText().toString());
                            int minutesPh = Integer.parseInt(minutesText.getText().toString());

                            SharedPreferences.Editor editor = prefs.edit();
                            bsPlaceholder = getMillisForCrafting(daysPh, hoursPh, minutesPh);
                            DateTime dt = new DateTime();
                            bsProgress = dt.getMillis();

                            editor.putBoolean("bs is running", bsIsRunning).commit();
                            editor.putLong("savedOnBsClick", bsProgress).commit();
                            editor.putLong("saved placeholder", bsPlaceholder).commit();

                            Long bsPlaceholderLong = bsPlaceholder;
                            final Integer setMax = Integer.valueOf(bsPlaceholderLong.intValue());

                            bsProgressBar.setMax(setMax);

                            daysText.setText("");
                            hoursText.setText("");
                            minutesText.setText("");

                            bsCountDownTimer.start();



                        }
                 })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) { 
                        dialog.dismiss();
                    }
                 })
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
            }return;

        }

            public static Long getMillisForCrafting(int daysPh, int hoursPh, int minutesPh) {
                    Locale.getDefault();
                    DateTime bs = new DateTime();
                    daysPulled = daysPh;
                    hoursPulled = hoursPh;
                    minutesPulled = minutesPh;

                    final long nowInMillis = bs.getMillis();


                    long days = daysPulled * 86400000;
                    long hours = hoursPulled * 3600000;
                    long minutes = minutesPulled * 60000;
                    long millisToAddToNow = days   hours   minutes;
                    long futureDateInMillis = millisToAddToNow   nowInMillis;
                    long millisFromDate = futureDateInMillis - nowInMillis;




                    return millisFromDate;
                }


            public void onBsResetButtonClick(View view) {
                final SharedPreferences prefs = this.getPreferences(Context.MODE_PRIVATE);
                bsTimeStamp = prefs.getLong("savedOnBsClick", bsProgress);
                        new AlertDialog.Builder(this)
                            .setTitle("Reset Timer?")
                            .setMessage("Reset Blacksmithing Research timer? n(Current timer will be erased.)")
                            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) { 

                                    j=0;
                                    bsProgressBar.setProgress(0);
                                    bsCountDownTimer.cancel();
                                    bsIsRunning=false;

                                    String progressBarTitleBs = "blacksmithing research";
                                    timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
                                    timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));

                                    bsPlaceholder = 0;
                                    bsTimeStamp = 0;
                                    SharedPreferences.Editor editor = prefs.edit();
                                    editor.putBoolean("bs is running", bsIsRunning).commit();
                                    editor.putLong("savedOnBsClick", 0).commit();
                                    editor.putLong("saved placeholder", 0).commit();

                                    // CLEAR INPUT EDITTEXT AREAS
                                    EditText daysText = (EditText)findViewById(R.id.editTextDays);
                                    EditText hoursText = (EditText)findViewById(R.id.editTextHours);
                                    EditText minutesText = (EditText)findViewById(R.id.editTextMinutes);
                                    daysText.setText("");
                                    hoursText.setText("");
                                    minutesText.setText("");
                                    // CLEAR INPUT EDITTEXT AREAS

                                }})
                            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) { 
                                    dialog.dismiss();
                                }
                             })
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .show();

                        }

    @SuppressLint("DefaultLocale") 
    public static String convertMillis(long milliseconds){
        long seconds, minutes, hours;
        seconds = milliseconds / 1000;
        minutes = seconds / 60;
        seconds = seconds % 60;
        hours = minutes / 60;
        minutes = minutes % 60;

        Locale.getDefault();
        String time = String.format("d:d:d", hours, minutes, seconds);
        return(time);
        }

    @SuppressLint("DefaultLocale") 
    public static String convertMillisForCrafting(long milliseconds){
        long seconds, minutes, hours, days;
        seconds = milliseconds / 1000;
        minutes = seconds / 60;
        seconds = seconds % 60;
        hours = minutes / 60;
        days = hours / 24;
        hours = hours % 24;

        minutes = minutes % 60;

        Locale.getDefault();
        String timeBs = String.format("d days d hours d minutes d seconds", days, hours, minutes, seconds);
        return(timeBs);
        }



    @Override
    protected void onDestroy() {
        super.onDestroy();  // Always call the superclass

        mProgressBar.destroyDrawingCache();
        mountCountDownTimer.cancel();
//      bsProgressBar.destroyDrawingCache();
//      bsCountDownTimer.cancel();
//      android.os.Debug.stopMethodTracing(); // Stop method tracing that the activity started during onCreate()
    }

}
  

Комментарии:

1. Просмотрев ваш код, я полагаю, что ваша проблема, возможно, больше похожа на простую логическую проблему. Я не решил эту проблему, но я скажу, что, я думаю, вам нужно проверить, правильно ли установлена ваша переменная bsIsRunning (Boolean). Если он установлен неправильно, может возникнуть проблема с вызовом onResume(), что имело бы смысл, почему он запускается при переключении действий и навигации по нему, но когда вы хотите, чтобы это было по-другому, это не работает.

2. Спасибо за ваш вклад, я собираюсь исследовать bsIsRunning во всех случаях. Однако, чтобы улучшить этот вопрос для любых других, которые могут его читать, проблема, описанная в вопросе, предшествует созданию логической переменной bsIsRunning. Другими словами, у меня была эта проблема до того, как я создал эту переменную и разместил ее в нескольких местах.

Ответ №1:

Я понял!

CountDownTimer не запускается, потому что переменная из onBsButtonClick() (bsPlaceholder) неправильно передается в onCreate().

Вот что я сделал:

Объявлена глобальная переменная

 static long timeInput;
  

Создан подкласс, который расширяет CountDownTimer:

     public class bsTimer extends CountDownTimer {

    public bsTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
    }

    @Override
    public void onTick(long millisInFuture) {
        Log.v("bsTimer", "Tick of Progress "   ji   " "   millisInFuture);
        ji =1;
        j =1000;
        bsProgressBar.setProgress(j);
        ((TextView)findViewById(R.id.bs_countdown)).setText(convertMillisForCrafting(millisInFuture-ji));

    }

    @Override
    public void onFinish() {
        // TODO Auto-generated method stub

    }

}
  

Создан экземпляр таймера обратного отсчета в onCreate();

 bsCountDownTimer = new bsTimer(timeInput, 1000);
  

Затем просто создал новый таймер и запустил его в методе onBsButtonClick()!

 bsCountDownTimer = new bsTimer(timeInput, 1000).start();