如何避免在启动 Activity 时调用 onCreate()?

Posted

技术标签:

【中文标题】如何避免在启动 Activity 时调用 onCreate()?【英文标题】:How do I avoid onCreate() being called when starting an Activity? 【发布时间】:2011-10-17 20:37:35 【问题描述】:

我想从堆栈中重新加载一个活动。

我使用startActivity() 开始新的活动。当我在 Activity D 上时,我想重新加载 Activity A 而不是启动新的 Intent。从 D 调用 A 时我不能使用 startActivity(),因为它会触发 onCreate(),从而启动一个线程来获取一些数据。

编辑:更新堆栈。

如果我使用FLAG_ACTIVITY_REORDER_TO_FRONT,它会再次调用onCreate() 方法。

以下是我的场景。

Login Activity ̣→ Activity A → Activity B → Activity C → Activity D → Activity A

如何避免onCreate() 被调用?

【问题讨论】:

【参考方案1】:

您必须采取完全不同的方法。使用startActivity()startActivityForResult() 启动Activity 无关紧要,因为启动Activity 时将调用onCreate()onStart()onResume()

现在,如果您的 Activity 类中有一个方法可以启动另一个线程来完成某些工作,那么您必须使用标志。如果您的 Activity 需要在第一次执行时自动启动线程,那么您必须将其包裹在 if 子句中以检查您在第一次运行时设置的标志。

这个想法是让您的 Activity 在您的Application 实例或SharedPreferences 中在线程首次执行时将布尔值设置为true。当您返回该 Activity 并且不希望该线程由于 onCreate() 被调用而自动运行时,您必须将调用代码包装在一些 if 子句中,如下例所示。

这是一个例子。

@Override
public void onCreate(Bundle bundle) 
    super.onCreate(bundle);
    // Other stuff

    if (!YourApplicationInstance.wasCalled) 
        // Run your thread or do something else you want to do only once.

        // Set the wasCalled flag to true to not run this code again
        // if onCreate() is called a second time.
        YourApplicationInstance.wasCalled = true;
    

您必须阅读 Using Application context everywhere? 才能了解如何实现我的伪类 YourApplicationInstance

【讨论】:

【参考方案2】:

清单中有一个名为launchMode 的标记用于活动。结帐此link。这不会调用 onCreate,但会调用 onNewIntent,你可以在其中重新初始化你的东西。

【讨论】:

【参考方案3】:

以下内容不正确。 startActivityForResult() 和 startActivity() 只是被调用Activity的返回目标不同

尝试使用 startActivityForResult() 而不是 开始活动()。我相信这并没有完全结束活动并重新开始。一世 建议使用此链接以进一步了解如何实现这种方法。

所以@Kgrover 的第 2 点也不成立。

Intent 标志 http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT 正是这样做的。

只要您有以活动转换为中心的需求,请留意 Intent 标志。该系统有很好的支持。

这相当于 Sam Quest 的解决方案,唯一的区别是如果您设置 launchMode,您的 Activity 的堆栈行为是硬编码的,即您的 Activity A 始终处于 singleTask 模式。

【讨论】:

【参考方案4】:

1) 虽然我不确定,但您可以尝试使用 startActivityForResult() 而不是 startActivity()。我相信这并没有完全结束活动并重新开始。我建议使用this 链接,以便进一步了解如何实现这种方法。

2) 或者,当您从活动 D -> A 开始时,继续使用 startActivity(),但传入一个 dummy extra。然后在活动 A 中,使用 if 语句:

 if(!(this.getIntent().hasExtra("dummyStringExtra")) 
  //fire the data thread here 

干杯。我希望这会有所帮助。

【讨论】:

注意:注意if语句中的!【参考方案5】:
@Override
public boolean onOptionsItemSelected(MenuItem item) 
    switch (item.getItemId()) 
        case android.R.id.home:
            this.finish();
            return true; 
    
    return super.onOptionsItemSelected(item);

这将杀死子活动。所以不会重新创建父活动

【讨论】:

以上是关于如何避免在启动 Activity 时调用 onCreate()?的主要内容,如果未能解决你的问题,请参考以下文章

Android生命周期与Intent笔记

视频结束时调用下一个活动

Android生命周期

如果在 Activity 更改时调用 onCreate 和 onStart 两者之间的区别在哪里?目的是啥?

Activity生命周期

Menu菜单