如何完成销毁活动

Pan*_*ang 11 android activity-lifecycle android-activity

据我了解,被销毁的活动并不等同于正在完成的活动.

  • 成品
    • 活动将从后台堆栈中删除.
    • 它可以由程序触发(例如通过调用finish()),或者由用户按下后退键(隐式调用finish())触发.
    • 完成一项活动将摧毁它.
  • 摧毁
    • Android操作系统可能会破坏不可见的活动以恢复内存.当用户导航回活动时,将重新创建活动.
    • 当用户旋转屏幕时,活动将被销毁并重新创建.
    • 参考:重新创建活动

那么如何完成被破坏的活动呢?该finish()方法需要一个Activity对象,但如果活动被销毁,我没有Activity对象 - 我不应该持有对被破坏活动的引用,是吗?


案例分析:

我有一个活动a,它开始b,然后开始c(使用Activity.startActivity()),所以现在后面的堆栈是:

a ? b ? c
Run Code Online (Sandbox Code Playgroud)

c,用户填写表单并点击"提交"按钮.使用的远程服务器发出网络请求AsyncTask.任务完成后,我会显示一个祝酒词并通过调用完成活动c.finish().完善.

现在考虑这种情况:

当异步任务正在进行时,用户切换到另一个应用程序.然后,Android操作系统决定销毁所有3个活动(a,b,c)由于存储器约束.之后,异步任务完成.现在我该如何完成c

我尝试过的:

android.util.AndroidRuntimeException:从Activity上下文外部调用startActivity()需要FLAG_ACTIVITY_NEW_TASK标志.这真的是你想要的吗?

编辑: 澄清:我需要等到异步任务完成,然后c根据服务器的响应决定是否完成.

Pan*_*ang 0

无法直接完成已销毁的活动,因此只需将finish()其放入其中onCreate()(由@Labeeb P建议)。就是这样:

  1. 如果该活动在尝试完成时已被销毁,请在某处保存一个布尔标志。

    if(activity != null)
    {
        // Activity object still valid, so finish() now.
        activity.finish();
    }
    else
    {
        // Activity is destroyed, so save a flag.
        is_activity_pending_finish = true;
    }
    
    Run Code Online (Sandbox Code Playgroud)
    • 如果即使应用程序被销毁,该标志也需要保留,请使用持久存储,例如SharedPreferences(由@Labeeb P建议)。
  2. 在活动中onCreate(),检查标志并调用finish()

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    
        if(is_activity_pending_finish)
        {
            is_activity_pending_finish = false; // Clear the flag.
    
            // This activity should have been finished, so finish it now.
            finish();
            return;
        }
    
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
    • 如果同一 Activity 类有多个实例,您可能需要的不仅仅是布尔标志来识别要完成的特定活动实例。

调用实际上finish()onCreate()一个合法的操作,正如文档中提到的:

...您可能会finish()从内部调用onCreate()来破坏该活动。在这种情况下,系统会立即调用,onDestroy()而不调用任何其他生命周期方法。


其他考虑因素:

  • 当应用程序处于后台时完成一项活动可能不是一个好主意,尤其是当它是唯一的活动时。确保不会让用户感到困惑。
  • 为了获得更好的用户体验,如果您在应用程序处于后台时完成了一项活动,您可能需要通知用户。考虑使用toast(适用于短暂通知)或通知(适用于用户可能忘记的长时间操作)(由@Stephan Branczyk@dilix建议)。

当然,被销毁的 Activity 并不一定意味着应用程序处于后台(可能还有另一个前台 Activity)。尽管如此,上述解决方案(调用finish())仍然onCreate()有效。