我面临一个我无法解决的奇怪问题。问题是,我有一个活动,按下按钮后我改变了一些布局的可见性。之后,我使用Handler
以便在4秒后恢复该情况,并将所有内容放在原来的位置。
一切都按预期工作,除非我更改设备方向,如果我在此过程中更改设备方向,我的视图将无法恢复,我不确定问题出在哪里:S。
以下是相关代码
private View mLoginFormView;
private View mLoginStatusView;
private boolean mLogginIn = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_layout);
mLoginFormView = findViewById(R.id.login_form);
mLoginStatusView = findViewById(R.id.login_status);
if (savedInstanceState == null) {
mLogginIn = false;
} else {
mLogginIn = savedInstanceState.getBoolean(getString(R.string.user_login_in),false);
Log.d(TAG,"RESTORING MLOGIN IN = " + mLogginIn);
}
findViewById(R.id.sign_in_button).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});
if(mLogginIn)
showProgress(true);
}
现在我介绍相关的功能
//.......
public void attemptLogin() {
showProgress(true);
mMenu.findItem(R.id.started).setVisible(false);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
showProgress(false);
Log.d(TAG,"MLOGGIN VALUE PROGRESS = " + mLogginIn);
mLogginIn = false;
}
});
}
},4000);
}
ShowProgress()
private void showProgress(final boolean show) {
mLogginIn = show;
Log.d(TAG, "showProgress " + mLogginIn);
int shortAnimTime = getResources().getInteger(
android.R.integer.config_shortAnimTime);
mLoginStatusView.setVisibility(View.VISIBLE);
mLoginStatusView.animate().setDuration(shortAnimTime)
.alpha(show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLoginStatusView.setVisibility(show ? View.VISIBLE
: View.GONE);
}
});
mLoginFormView.setVisibility(View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(show ? 0 : 1)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE
: View.VISIBLE);
}
});
}
最奇怪的是,在执行onRestoreInstanceState
代码后调用postDelayed
时,mLogginIn
显示前一个值(true),就好像它没有效果一样所有
提前致谢
答案 0 :(得分:4)
由于配置更改而重新创建Activity
时,它是一个完全不同的对象实例,具有另一个嵌入式视图层次结构。您的Handler
对旧对象实例很紧张,因此它也会修改旧的视图层次结构。因此,你什么也看不见。
不要这样做:它会泄漏内存并可能导致崩溃。
解决方案:
发布Runnable
时,请将Runnable
实例和当前时间戳保存在两个引用中。如果Runnable
正常运行,请将时间戳设置为-1(在Runnable
代码中)。
如果时间戳与-1不同,则在onSaveInstanceState(Bundle)
上保留配置更改,并使用Handler.removeCallbacks(Runnable)
从处理程序中删除可运行的回调。
重新创建活动时,恢复时间戳并计算与当前时间的差异。使用此延迟发布具有相同逻辑的新Runnable
(如果它为0或否定,您可能希望直接运行runnable而不是发布它)。此Runnable
现在对Activity
的新实例很紧张。
答案 1 :(得分:1)
当设备方向改变时,您的活动将被销毁,并且会创建新活动并通过savedInstanceState包恢复状态。但是你使用postDelayed发布的runnable是一个与原始活动相关的匿名内部类。此活动对象仍然存在,您的runnable会修改它,但它不再可见。
您当前的架构不起作用,您必须选择其他架构才能达到您想要的效果。