Android Activity 旋转刷新

Android Activity Refreshing On Rotation

我是一位经验丰富的 .NET 开发人员,但这是我的第一个 Android 应用程序,它让我抓狂!

这是一个工作正常的倒数计时器,但是当您旋转屏幕时,它会重新初始化 activity,从而使倒计时归零并停止。

这是我试过的; 我摆脱了 CountDownTimer object,而是在 activity 内部创建了一个 class,它扩展了 AsyncTask,所以它 运行 在一个单独的线程上......没有变化。 我认为它是一个内部 class 它正在用 activity.

重新初始化

这是我接下来尝试的; 我将 class 设为外部。 Activity 将其上下文传递给 class 并且上下文中的 onProgressUpdate 和 onPostExecute 运行 public 函数更新 activity 的 UI . 同样,这在您旋转它之前工作正常...... Aaaargh!

然而,我发现异步 class 仍然是 运行ning 但 UI 没有改变,因为(我认为)activity 现在有一个与异步 class 引用的上下文不同。

这就是我所在的位置。每个解决方案解决一个问题并创建另一个问题。 我需要以某种方式维护上下文还是我开始追逐自己的尾巴?

任何帮助将不胜感激!

他。 巴里

However, I discovered that the async class is still running but the UI doesn't change because (I think) the activity now has a different context to the one the async class has reference to.

不错的猜测。如果你想保留计算数据,你必须处理 Activity's lifecycle,因为无论何时旋转设备,都会重新创建 activity,因此 onCreate() 被调用 保存之前的计算数据。您必须覆盖 onSaveInstanceState(Bundle savedInstanceState)onRestoreInstanceState() 才能保存您的计算。看看Activity's LifeCycle documentation and Reto Meier's answer,我想它会解决你的问题。

Try_me34的解决方案很好,但这里有一些其他保存和恢复数据的方法(不能post它们作为评论):

尝试覆盖 onPause 方法并将过程保存到辅助 class(也许是定时器),然后恢复它覆盖 onResume.

另一种选择是将其保存为首选项:

SharedPreferences.Editor editor = getSharedPreferences("nameOfFile", MODE_PRIVATE).edit();
editor.putInt("name", value);
editor.putString("nameForString", value);

然后加载它:

SharedPreferences prefs = getSharedPreferences("nameOfFile", MODE_PRIVATE);
int i = prefs.getInt("tag", 0);
String s = prefs.getString("tag", "defaultValue");

在您的 CountDownTimer 工具中 onTick:

@Override
public void onTick(long millisUntilFinished) {
    // something like this:
    this.millisUntilFinished = millisUntilFinished;
}

在您的 Activity 工具中 onSaveInstanceState:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // something like this:
    savedInstanceState.putLong("millisUntilFinished", millisUntilFinished);
}

也在 onCreateonStart 中重新设置您的 CountDownTimer:

@Override
public void onCreate(Bundle savedInstanceState) {
    // ...

    if (savedInstanceState != null) {
        millisUntilFinished = savedInstanceState.getLong("millisUntilFinished");
    }

}

@Override
public void onStart() {
    super.onStart();
    timer = new MyCountDownTimer(millisUntilFinished, 100); 
    timer.start();
}

不要逐字复制此代码,有一些细节 missing/assumptions 在您的代码中会有所不同,但它可能看起来像这样。