简体   繁体   English

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

[英]How do I avoid onCreate() being called when starting an Activity?

I want to reload an activity from stack. 我想从堆栈重新加载一个活动。

I use startActivity() to start new activities. 我使用startActivity()来开始新的活动。 When I'm on Activity D I want to reload Activity A and not start a new Intent. 当我在活动D上时,我想重新加载活动A而不是启动新的意图。 I can't use startActivity() when calling A from D because it will fire onCreate() which starts a thread to fetch some data. D调用A时我不能使用startActivity() ,因为它将触发onCreate() ,它启动一个线程来获取一些数据。

EDIT : Updated the stack. 编辑 :更新了堆栈。

If I use FLAG_ACTIVITY_REORDER_TO_FRONT it calls the onCreate() method again. 如果我使用FLAG_ACTIVITY_REORDER_TO_FRONT它会再次调用onCreate()方法。

Following is my scenario. 以下是我的情景。

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

How do I avoid onCreate() being called? 如何避免调用onCreate()

You have to take a totally different approach. 你必须采取完全不同的方法。 It doesn't matter if you start your Activity with startActivity() or startActivityForResult() because onCreate() , onStart() and onResume() will be called when you start an Activity. 如果使用startActivity()startActivityForResult()启动Activity并不重要,因为在启动Activity时将调用onCreate()onStart()onResume()

Now if you have a method in your Activity class that starts another thread to do some work then you have to work with flags. 现在,如果你的Activity类中有一个方法启动另一个线程来做一些工作,那么你必须使用标志。 If your Activity requires to automatically start the thread on first execution then you have to wrap it around an if clause to check for a flag you set when it is first run. 如果您的Activity需要在第一次执行时自动启动线程,那么您必须将其包装在if子句周围以检查您在首次运行时设置的标志。

The idea is to have your Activity set a boolean to true in either your Application instance or SharedPreferences when the thread is first executed. 我们的想法是在首次执行线程时,在Application实例或SharedPreferences中将Activity设置为true。 When you come back to that Activity and don't want that thread to be run automatically due to onCreate() being called then you have to wrap your calling code around some if clause like in the example below. 当你回到那个Activity并且不希望由于onCreate()被调用而自动运行该线程时,你必须将你的调用代码包装在一些if子句中,如下例所示。

Here is an example. 这是一个例子。

@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;
    }
}

You'll have to read Using Application context everywhere? 你必须阅读在任何地方使用应用程序上下文? to understand how to implement my pseudo class YourApplicationInstance . 了解如何实现我的伪类YourApplicationInstance

there is tag called launchMode for activity in the manifest. 清单中有活动的标签叫做launchMode。 checkout this link . 结帐此链接 and this will not call onCreate but it will call onNewIntent, where you can reinitialize you stuff. 这不会调用onCreate但会调用onNewIntent,你可以重新初始化你的东西。

The following is not true. 以下情况并非如此。 startActivityForResult() and startActivity() only differ in the return target of the called Activity startActivityForResult()和startActivity()仅在被调用的Activity的返回目标中有所不同

try using startActivityForResult() rather than startActivity(). 尝试使用startActivityForResult()而不是startActivity()。 I believe this does not completely end the activity and start it again. 我相信这并没有完全结束活动并重新开始。 I would recommend using this link in order to further read on how to implement such a method. 我建议使用此链接以进一步阅读如何实现此类方法。

So point 2 of @Kgrover does not hold too. 所以@Kgrover的第2点也不成立。

The Intent flag http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT does exactly this. Intent标志http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT就是这样做的。

Keep an eye out on the Intent flags whenever you have requirements centered around Activity transitions. 每当需求以活动转换为中心时,请留意Intent标志。 The system has excellent support. 该系统具有出色的支持。

This is equivalent to Sam Quest's solution, the only difference being that if you set the launchMode , the stack-behavior of your Activity is hardcoded ie your Activity A is always in the singleTask mode. 这相当于Sam Quest的解决方案,唯一的区别是如果设置launchMode ,您的Activity的堆栈行为是硬编码的,即您的活动A始终处于singleTask模式。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            this.finish();
            return true; 
    }
    return super.onOptionsItemSelected(item);
}

This will kill the child activity. 这会杀死孩子的活动。 So parent activity is not recreated 因此不会重新创建父活动

1) Although I am not sure, you could try using startActivityForResult() rather than startActivity(). 1)虽然我不确定,但您可以尝试使用startActivityForResult()而不是startActivity()。 I believe this does not completely end the activity and start it again. 我相信这并没有完全结束活动并重新开始。 I would recommend using this link in order to further read on how to implement such a method. 我建议使用链接以进一步阅读如何实现此类方法。

2) Alternatively, when you go from activity D -> A, continue to use startActivity(), but pass in a dummy extra. 2)或者,当你从活动D - > A开始时,继续使用startActivity(),但传入一个虚拟额外的。 Then in activity A, use an if statement: 然后在活动A中,使用if语句:

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

Cheers. 干杯。 I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM