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);
}
也在 onCreate
和 onStart
中重新设置您的 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 在您的代码中会有所不同,但它可能看起来像这样。
我是一位经验丰富的 .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);
}
也在 onCreate
和 onStart
中重新设置您的 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 在您的代码中会有所不同,但它可能看起来像这样。