Восстановить объект CountDownTimer после поворота - PullRequest
1 голос
/ 12 июля 2019

Когда я вращаюсь, вызывается метод onCreate, поэтому я теряю все свои переменные, поэтому я хочу восстановить объект CountDownTimer.Методы обратного вызова onTick и onFinish объекта CDT активны, так как countdownTimer продолжает работать.Я думаю, что решение состоит в том, чтобы сделать parcable объект, но мне не удалось завершить мой коднужна услуга

   //my try to make parsable the CDT object    
    public class MyCountDownTimer implements Parcelable {
            private CountDownTimer t;

            public  final Parcelable.Creator CREATOR = new Parcelable.Creator() {
                public MyCountDownTimer createFromParcel(Parcel in) {
                    return new MyCountDownTimer(in);
                }

                public MyCountDownTimer[] newArray(int size) {
                    return new MyCountDownTimer[size];
                }
            };

            private MyCountDownTimer(Parcel in) {
                t = (CountDownTimer) in.readParcelable(Timer);
            }
            MyCountDownTimer(CountDownTimer t)
            {
                this.t =t;
            }

            @Override
            public int describeContents() {
                return 0;
            }

            @Override
            public void writeToParcel(Parcel parcel, int i) {

            }
        }


    //declaretion
    private CountDownTimer Timer;

    protected void onSaveInstanceState(@NonNull Bundle outState){
         super.onSaveInstanceState(outState);
         outState.putSerializable(COUNTDOWN,new MyCountDownTimer(Timer));
    }

    //on restore
    Timer = (CountDownTimer) savedInstanceState.getParcelable(COUNTDOWN);


    //when call Timer
     private void setTimer(long mTimeLeftInMillisfun){

            Timer = new CountDownTimer(mTimeLeftInMillisfun,1000) {
                @Override
                public void onTick(long l) {


                    textTimer.setText("Remain "+ l/1000+" Seconds");

                }

                @Override
                public void onFinish() {
                    //do sth
                }


            }.start();
        }

Ответы [ 3 ]

0 голосов
/ 12 июля 2019

Не отправляйте свой таймер. Вы потеряете время на часах (может быть не много, но все же) во время процесса посылки / отмены посылки.

Используйте ViewModel для выживания вашего таймера во время изменения конфигурации (ротация активности).

https://developer.android.com/topic/libraries/architecture/viewmodel

Пример кода -

public class MyViewModel extends ViewModel {

private CountDownTimer countDownTimer;
private MutableLiveData<Long> timerLiveData;

public MyViewModel() {
    this.timerLiveData = new MutableLiveData<>();
}

public LiveData<Long> getTimerLiveData() {
    return timerLiveData;
}

public void requestTimer(long timeInMins) {
    if (countDownTimer != null) {
        countDownTimer.cancel();
    }

    countDownTimer = new CountDownTimer(timeInMins * 60 * 1000, 1000) {

        public void onTick(long millisUntilFinished) {
            timerLiveData.setValue(millisUntilFinished);
        }

        public void onFinish() {
            timerLiveData.setValue(0L);
        }
    };
    countDownTimer.start();
}

}

Прослушивание таймера из пользовательского интерфейса -

myViewModel.getTimerLiveData().observe(this, timeLeft -> Log.d("test", "timeLeft " + timeLeft);
0 голосов
/ 12 июля 2019

Это определение для CountDownTimer.java, оно не реализует интерфейс Parcelable:

public abstract class CountDownTimer {

    /**
     * Millis since epoch when alarm should stop.
     */
    private final long mMillisInFuture;

    /**
     * The interval in millis that the user receives callbacks
     */
    private final long mCountdownInterval;

    private long mStopTimeInFuture;

    /**
    * boolean representing if the timer was cancelled
    */
    private boolean mCancelled = false;
    ...

И вы пытаетесь создать неразборчивый объект, который можно будет разложить на следующий код:

//my try to make parsable the CDT object    
    public class MyCountDownTimer implements Parcelable {
            private CountDownTimer t;

Это невозможно (поправьте меня, если есть какой-либо способ сделать это), если только вы не сохраните данные внутри CDT в onSaveInstanceState и не восстановите их с данными, сохраненными в onCreate.

0 голосов
/ 12 июля 2019

Чтобы восстановить ваш объект при изменении конфигурации, вам необходимо сохранить его в savedInstanceState:

 override fun onSaveInstanceState(outState: Bundle) {
    outState.putParcelable("your_parcelable_object", myCountDownTimer)
    super.onSaveInstanceState(outState)
}

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    super.onRestoreInstanceState(savedInstanceState)
    myCountDownTimer = savedInstanceState?.getParcelable<MyCountDownTimer>("your_parcelable_object")
}
...