【问题标题】:Restore CountDownTimer object after rotation旋转后恢复 CountDownTimer 对象
【发布时间】:2019-07-11 22:12:27
【问题描述】:

当我旋转时,会调用 onCreate 方法,所以我会丢失所有的变量,这就是我想要恢复 CountDownTimer 对象的原因。 CDT 对象的 onTick 和 onFinish 回调方法在 countdownTimer 继续运行时处于活动状态。我认为解决方案是使对象可解析,但我没有设法完成我的代码

我不想使用服务,因为 Android 文档在使用服务时是特别的,我认为在我的情况下我不需要服务

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

【问题讨论】:

  • 您要保存CountDownTimer 对象还是只保存CountDownTimer 中的数据?如果只是数据,你不需要让你的类实现Parcelable

标签: android bundle parcelable countdowntimer onsaveinstancestate


【解决方案1】:

不要包裹你的计时器。在包裹/拆包过程中,您将在时钟上浪费时间(可能不会很多,但仍然如此)。

在配置更改(活动轮换)期间使用 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();
}

}

从 UI 监听计时器 -

myViewModel.getTimerLiveData().observe(this, timeLeft -> Log.d("test", "timeLeft " + timeLeft);

【讨论】:

  • 您能提供一些代码吗?我已经有一个 viewModel 但我用来保存来自 db @Vishal Arora 的数据
  • public void saveTimer (CountDownTimer t) { this.timer = t; } public CountDownTimer getTimer() { return timer; } 我只是在我的 ViewModel 中创建这样的东西
  • 是的,先生,您的解决方案已被接受。但是,我稍微编辑了您的解决方案。我的意思是?!?!在我的视图模型中,我为 CountDownTimer 创建了 1 个 setter 和 1getter 方法。这样,当我在我的活动中创建一个 CDT obj 时,我通过调用 setter 方法将此对象存储在视图模型中,并且 onInstanceState 我从 ViewModel 调用 getter 方法以检索它。它也有效。这是代码示例private CountDownTimer timer public void saveTimer (CountDownTimer t) { this.timer = t; } public CountDownTimer getTimer() { return timer; }
【解决方案2】:

要在配置更改时恢复您的对象,您需要将其保存在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")
}

【讨论】:

  • 感谢您的回答,但我的问题是使 countdownTimer 对象可打包。
【解决方案3】:

这是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 中的数据进行恢复。

【讨论】:

  • 是的,那是我的错
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多