Nexus 5进入睡眠模式会使活动生命周期变得越来越糟糕

时间:2014-04-01 08:04:02

标签: android multithreading threadpool android-lifecycle nexus-5

进入和退出睡眠模式时,我在Nexus 5上有一种奇怪的行为。它以一种非常奇怪的方式杀死并重新启动应用程序。我告诉你日志:

进入睡眠模式(按电源按钮)

17.005:E / MotherActivity(28940):onPause叫做
17.025:E / MotherActivity(28940):onStop称为
17.315:E / MotherActivity(28940):onDestroy称为
17.365:E / GameTuto1Activity(28940):MainActivity构造函数称为
17.365:E / MotherActivity(28940):onCreate称为
17.695:E / MotherActivity(28940):onStart称为
17.705:E / MotherActivity(28940):onResume称为
17.705:E / MotherActivity(28940):onPause名为

从睡眠模式回来,解锁手机时

755:E / MotherActivity(28940):onResume称为
 935:E / MotherActivity(28940):onPause称为
935:E / MotherActivity(28940):onStop名为

然后手机才会响起,直到我杀死这个过程。但是为什么我在恢复我的应用程序(从睡眠模式回来)时会经历onPause和onStop以及为什么onCreate,OnStart,onResume,onPause在进入睡眠模式时?

如果我对Nexus7做同样的事情,它就不会发生,生命周期是“正常的”。以下日志:

进入睡眠模式(按电源按钮)

43.782:E / MotherActivity(19876):onPause调用 43.822:E / MotherActivity(19876):onStop名为

从睡眠模式回来,解锁手机时

50.142:E / MotherActivity(19876):onRestart致电 50.142:E / MotherActivity(19876):onStart调用 50.172:E / MotherActivity(19876):onResume叫

这个问题很奇怪,也许是错误的(也许),但答案可能非常聪明。 如果你有想法? 它只发生在我有3个线程的项目中:2个循环线程(我在onPause中杀死)和一个由PoolExecutor管理的线程(在onPause中也被杀死)。如果我做一个简单的应用程序,它不会被复制。 Nexus5版本= 4.4.2,nexus7版本= 4.2.2
我知道,这个问题没有代码,我无法分享我的项目 但是,提前感谢所有想起这个问题的人 马蒂亚斯 .... 5个小时后:A导致答案 ...... 在我的活动清单中,我有:

<activity  
        android:name=".MainActivity"  
        android:label="@string/title_activity_main"  
        **android:screenOrientation="landscape"**
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >  
        <intent-filter>  
        <action android:name="android.intent.action.MAIN" />  
            <category android:name="android.intent.category.LAUNCHER" />  
        </intent-filter>  
    </activity>  

如果我删除android:screenOrientation =“landscape”,它就可以了。 为什么会发生这种情况?为什么我不能将我的方向设置为横向并忘记configurationChange事件 最糟糕的是,如果我听取方向配置改变了:

android:configChanges="orientation"

没有调用onConfigurationChanged方法!!!但如果我使用:     机器人:configChanges = “方向|屏幕尺寸” 并覆盖onConfiguration它有效....

为什么在地球上,screenOrientation = landscape无法处理screenSize配置更改。有没有另一种干净的方法来处理这个混乱,只是对系统说,“当我把我的手机置于睡眠模式时,我处于横向模式的人不会把我搞砸为肖像”。 如果有人在这里知道,谢谢你的回答。

否则,这意味着如果您希望您的应用程序是纵向或横向,则需要将android:configChanges =“orientation | screenSize”添加到清单中并覆盖Activity中的onConfigurationChanged(不执行任何操作)。 OO'

1 个答案:

答案 0 :(得分:3)

因此,错误是由于方向改变...但不是真的。 实际上,当“Nexus 5进入睡眠模式”和“活动”处于“肖像”状态时,它不是“方向”改变(在我的情况下),而是“screenSize已更改”,作为configurationChange事件触发。在Nexus 7上没有发生这种情况,因为它的正常模式在进入睡眠时是风景,因此不会触发configurationChange。

解决方案
这意味着,在HoneyComb之后(因为慧聪网开始使用screenSize),如果在你的清单中,你正在使用

 android:screenOrientation="landscape"

您还需要在清单中包含以下这一行:

 android:configChanges="orientation|screenSize"

在您的MotherActivity(您的活动继承的那个)或您的活动中,您必须以这种方式覆盖配置更改方法:

 /*
 * (non-Javadoc)
 * @see android.app.Activity#onConfigurationChanged(android.content.res.Configuration)
 */
@Override
public void onConfigurationChanged(Configuration newConfig) {
    Log.e("MotherActivity", "onConfigurationChanged called ");
    // this method is there to ensure no configuration changes when going to sleep mode
    // because the device wants my app to go on portrait and then fire screenSize changes
    // sometime some montainview code sucks
    super.onConfigurationChanged(newConfig);
    // and of course do nothing !!!
}

可以看看这里是为了更好地理解onConfigurationChange以及如何处理它。@ http://developer.android.com/guide/topics/resources/runtime-changes.html

回到我的问题
在我的情况下,由于没有预期的配置更改,我正在与丢失的线程作斗争 简单技巧n°1
因此,避免这种痛苦并快速检测它的简单方法是在开发模式下将Log添加到您的Mother活动中。因此,在测试时,您始终可以记录活动的生命周期。它将帮助您避免生命周期的混乱 例:

/*
 * (non-Javadoc)
 * @see android.app.Activity#onCreate(android.os.Bundle)
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.e("MotherActivity", "onCreate called");
    super.onCreate(savedInstanceState);
}

主题法
最后,总是,我的意思是总是,深入了解你的线程(如果你有的话)并确保没有内存泄漏(线程必须死掉)并确保你的线程被保留(onRetainNonConfigurationInstance或使用没有GUI的片段和setRetainInstance(true))当配置更改或确保处理配置更改时 简单技巧n°2
另外一个技巧也是监听mcc和mnc(在你的清单android:configChanges =“orientation | screenSize | mcc | mcn”),因为你的应用程序大部分时间都不关心改变电信运营商。大多数时候你没有测试那个案例。

祝大家度过美好的一天!