Android Activity被随机创建和销毁

时间:2016-09-29 17:33:21

标签: android android-lifecycle android-bundle

我不了解如何管理Android活动。

我有一个活动,每隔一段时间我都注意到,当我的应用程序进入后台时,android会破坏当前活动(例如 Activity3 )以及其他几个单例和对象这很好。问题是当应用程序恢复时,直觉告诉我,因为android已经破坏了活动和对象的内存或其他什么,然后android将完全从 Activity1 重新启动应用程序所以所有对象和数据成员会得到适当的资助。

不是!

似乎当我的应用程序恢复时,会重新创建 Activity3 ,并使用与第一次相同的参数调用 onCreate (从中调用它时) Activity2 )此时,所有在 Activity1 Activity2 中初始化的单身人士和其他对象都会使用默认值重新创建,并且无法使用。

这是一个安全的政策/技术怎么样? Android如何随机销毁对象和活动,然后当用户恢复时,只需在最近的活动上调用onCreate,并期望一切都是hunky doory和< strong>不必经过正确的启动程序/初始化?

更新/解决方案

感谢评论员的出色信息。

根据ANDROID文档

  

的onCreate

     

Bundle:如果在之前关闭之后重新初始化活动,则此Bundle包含最近在onSaveInstanceState(Bundle)中提供的数据。注意:否则为空。

THEREFORE 我最终做的是设置两个标志。在Bundle中的 onSaveInstanceState 中有一个,所以要知道它是我设置的有效Bundle。另一个用于确定 onCreate 是否由于娱乐自动轮播而被调用。所以在 onCreate 中,我检查了 onSaveInstanceState 是否为空,检查Bundle标志,然后检查 bInit (默认为false)。如果两个标志都为真,则意味着android抛弃并销毁我们的应用程序内存,并确保在线性样式应用程序中再次初始化所有内容的最安全方法是重新启动它并启动开始活动。

public class SomeMiddleActivity extends AppCompatActivity
{
    private static boolean bInit = false; // only way it will be false again is if android cleared our memory and we are recreating

    @Override
    public void onSaveInstanceState(Bundle state)
    {
        // set a flag so that onCreate knows this is valid
        state.putBoolean("StateSaved", true);
        super.onSaveInstanceState(state);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        // this must be called first always for some reason
        super.onCreate(savedInstanceState);

        if (savedInstanceState != null)
        {
            if (savedInstanceState.getBoolean("StateSaved", false) && !bInit)
            {
                // we were recreated... start app over
                Intent intent = new Intent(getApplicationContext(), Startup.class);
                startActivity(intent);
                finish();
                return;
            }
        }

        bInit = true; // this will stay true until android has cleared our memory

        .......
    } 

虽然到目前为止一直有效,但如果有人有不同的建议,请告诉我。我将在此发表另一篇文章。

和FYI: onSaveInstanceState onSaveInstanceState(Bundle,PersistableBundle)版本永远不会被调用,所以我不知道为什么他们甚至实现它。 (?)

@goldenb @Rishabh感谢goldenb和Rishabh的见解。

2 个答案:

答案 0 :(得分:1)

Android,如果销毁,也会为您提供处理它的工具。

移动设备的内存量有限,需要在同时运行的应用程序之间共享。因此,智能资源分配是必要的。在前台运行的应用程序由最终用户使用,并获得高优先级以获得更好的性能和用户体验。因此,在后台运行的应用程序需要释放资源以满足前台应用程序的内存要求。因此,后台应用程序有时会被破坏(不完全)(在内存不足的情况下)。

Android活动的回调类似于 onSaveInstanceState()和onRestoreInstanceState(),这使您可以在销毁时保存当前的活动状态(即变量值),并在活动时检索它们重建。

您可以从此处获取更多信息:How to save and retrieve the state of Activity using onSaveInstanceState and onRestoreInstanceState.

您可以对已检索状态执行验证,以确保“活动”的执行方式与预先销毁时完全相同。一旦你亲自动手,你会发现它非常容易和合乎逻辑。

答案 1 :(得分:1)

在这个问题上给我50美分。处理系统因其背景资源而被杀的活动问题的正确方法是android中的常见问题,根据Google的解决方案是:

  

onPause()是您处理离开活动的用户的地方。最   重要的是,此时用户所做的任何更改都应该是   已提交(通常是持有数据的ContentProvider)。

重点是我的。但这意味着Android生命周期的设计是为了在正常条件下onPause应该被调用为Activity或Fragment被发送到后台。他们在几个android文档页面中暗示了这一点:

当您的活动进入暂停状态时,系统会调用您的活动上的onPause()方法,这样您就可以停止暂停时不会继续执行的操作(例如视频)或保留任何信息应该永久保存,以防用户继续离开您的应用。

另外值得您注意:如果您希望在Activity recreation期间恢复视图,则应设置所有视图的 ID 属性;)

  

注意:为了让Android系统恢复状态   您的活动中的视图,每个视图必须具有唯一的ID,由。提供   android:id属性。

PS。 你想知道为什么没有调用 onSaveInstanceState(Bundle,PersistableBundle),一种可能是你没有设置正确的活动属性

  

这与onRestoreInstanceState(Bundle)相同,但是被调用   使用属性 persistableMode 设置为创建的活动    persistAcrossReboots ..