相关问题:
这是我在我的活动中遇到的一种奇怪的行为。
肖像模式(这是正常的)
Activity: onPause()
; Activity: onResume()
。风景模式(很奇怪)
Activity: onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onResume()
加载纵向布局; Activity: onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onResume()
并加载横向布局。我的期望是:
肖像模式:(相同)
风景模式:(应该像肖像模式一样)
Activity: onPause()
; Activity: onResume()
。所以我的问题:
我的问题的原始文字说明:
当我按下手机的锁定屏幕按钮时,当我的活动处于横向模式时,我注意到(在我输出到Eclipse的调试消息中)活动被重新创建为其肖像模式(而屏幕是当然是全黑的)。然后当我再次按下锁定屏幕按钮解锁屏幕时,活动被销毁并再次重新创建其肖像。
正如我记得的那样(虽然不是100%肯定),而且我期望的是,我的活动只应该经历onSaveInstanceState()
和onPause()
,而横向模式下的锁定屏幕,就像它在肖像中所做的那样模式。而不是重新创建活动到肖像并再次返回景观。
我用手机弄乱了什么吗?我怎样才能恢复正常?
谢谢!
感谢大家为此问题做出贡献。特别感谢@HoanNguyen在他的设备中为我测试的努力。特别感谢@Raghunandan就这个问题与我进行了深入的讨论。
总结每个人到目前为止的贡献,我得出以下结论:
似乎在移动电话上,处于横向模式的正在运行的活动在屏幕锁定是正常行为时切换到纵向模式。至少到目前为止在测试手机上都是如此。因此,我们必须确保我们的生命周期功能始终能够优雅地关注这一变化。
我们没有关于此问题的文档或许多资源。但是假设在屏幕锁定时运行的活动切换回设备的“默认方向”,就像在大多数设备中锁定的屏幕是纵向一样,这是非常合乎逻辑的。
我只是想知道如果我们有横向锁定屏幕,活动会如何表现?
答案 0 :(得分:2)
您可以停止活动重定向更改,但这通常是一个非常糟糕的主意。
Android文档包含a section on handling runtime changes with this note:
注意:自行处理配置更改会使使用备用资源变得更加困难,因为系统不会自动为您应用这些资源。当您必须避免因配置更改而重新启动时,此技术应被视为最后的手段,并且不建议用于大多数应用程序。
如果您不需要备用资源和,Android通常只会建议您在轮播时进行重新创建,更重要的是,有性能要求。在大多数情况下,精心设计的应用程序不需要这样做。
如果你坚持沿着压制默认Android行为的道路,我会修改Raghunandan的代码并包含一个屏幕尺寸属性。从API级别13开始,屏幕尺寸在方向改变时改变。因此,除非您仅定位到API 12及更低版本,否则必须包含screenSize。
<activity android:name=".MyActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name">
答案 1 :(得分:0)
避免重启活动
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"//add tthis in manifest
android:label="@string/app_name">
http://developer.android.com/guide/topics/resources/runtime-changes.html
在正常情况下,当您的屏幕被锁定时,您的活动会暂停,当屏幕解锁时,活动会恢复。
屏幕锁定时出现的问题是:如果发现内存不足,系统可能会强制停止当前活动,而不是将活动移至背景。在这种情况下,我们必须保存(所有必要的数据)活动的当前状态。
将数据保存在onSaveInstanceState()中并恢复数据onRestoreInstanceState()。
@Override
public void onSaveInstanceState(Bundle outState)
{
Log.v("$````$", "In Method: onSaveInstanceState()");
//if necessary,set a flag to check whether we have to restore or not
//handle necessary savings…
}
@Override
public void onRestoreInstanceState(Bundle inState)
{
Log.v("$````$", "In Method: onRestoreInstanceState()");
//if any saved state, restore from it…
}
在你的onCreate()
中IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter); //register
public class ScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
Log.v("$$$$$$", "In Method: ACTION_SCREEN_OFF");
// onPause() will be called.
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
Log.v("$$$$$$", "In Method: ACTION_SCREEN_ON");
//onResume() will be called.
//Better check for whether the screen was already locked
// if locked, do not take any resuming action in onResume()
//Suggest you, not to take any resuming action here.
}
else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT))
{
Log.v("$$$$$$", "In Method: ACTION_USER_PRESENT");
//Handle resuming events
}
}
在你的onDestroy
中 @Override
public void onDestroy()
{
super.onDestroy();
Log.v("$$$$$$", "In Method: onDestroy()");
if (mReceiver != null)
{
unregisterReceiver(mReceiver); //unregister
mReceiver = null;
}
}