简体   繁体   English

重新启动活动时调用onStop延迟

[英]onStop delays to be called when restarting activity

When restarting an Activity, onStop() from previous activity delays too much to be called. 重新启动活动时,先前活动的onStop()延迟太多,无法调用。

I am using this code to restart my activity PlayerActivity.java 我正在使用此代码重新启动我的活动PlayerActivity.java

Intent playerIntent = getIntent();
playerIntent.putExtra(Constants.VIDEO_ID, videoId);
playerIntent.putExtra(Constants.CATEGORY_ID, categoryId);
playerIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(playerIntent);

Let's call PreviousPlayerActivity and NewPlayerActivity , the activity that was before and the new activity. 让我们分别调用PreviousPlayerActivityNewPlayerActivity ,之前的活动以及新的活动。 (remembering that they are the same PlayerActivity). (请记住,它们是相同的PlayerActivity)。

Sequence 序列

When restarting the app follows this flow in the activity-lifecycle. 重新启动应用程序时,将在活动生命周期中遵循以下流程。

PreviousPlayerActivity onPause() --> 
NewPlayerActivity onCreate() --> 
NewPlayerActivity onStart() --> 
NewPlayerActivity onResume() --> 
NewPlayerActivity performs a heavy operation --> 
PreviousPlayerActivity onStop() --> 
PreviousPlayerActivity onDestroy()

What I need 我需要的

I need PreviousPlayerActivity to be completed destroyed before NewPlayerActivity starts. 我需要在NewPlayerActivity启动之前完成销毁PreviousPlayerActivity。 However, onStop() is just called after the heavy operation, so it delays around 10 seconds to be called. 但是, onStop()在繁重的操作之后onStop()调用,因此它会延迟大约10秒钟的调用时间。

What I tried 我尝试了什么

If I use recreate() method it does destroy PreviousPlayerActivity before calling NewPreviousActivity, but by calling recreate() I can not putExtras into the new activity instance. 如果我使用recreate()方法,它会在调用NewPreviousActivity之前销毁PreviousPlayerActivity,但是通过调用recreate()我无法将Extras放入新的活动实例中。

Questions 问题

  1. How to completely destroy PreviousActivity when restarting an activity? 重新启动活动时如何完全销毁PreviousActivity?
  2. Is there a way to putExtras while using recreate() ? 使用recreate()时,有没有办法放置putExtras?

In Activity Lifecycle from Android Developer guide. 在《 Android开发人员指南的活动生命周期》中

Coordinating activities 协调活动

When one activity starts another, they both experience lifecycle transitions. 当一项活动开始另一项活动时,它们都会经历生命周期过渡。 The first activity stops operating and enters the Paused or Stopped state, while the other activity is created. 第一个活动停止操作,并进入“已暂停”或“已停止”状态,而另一个活动被创建。 In case these activities share data saved to disc or elsewhere, it's important to understand that the first activity is not completely stopped before the second one is created. 如果这些活动共享保存到磁盘或其他位置的数据,则必须了解在创建第二个活动之前,第一个活动并未完全停止。 Rather, the process of starting the second one overlaps with the process of stopping the first one. 相反,启动第二个进程的过程与停止第一个进程的过程重叠。

The order of lifecycle callbacks is well defined, particularly when the two activities are in the same process (app) and one is starting the other. 生命周期回调的顺序定义明确,尤其是当两个活动处于同一进程(应用程序)中并且一个活动正在启动另一个活动时。 Here's the order of operations that occur when Activity A starts Activity B: 这是活动A启动活动B时发生的操作顺序:

  1. Activity A's onPause() method executes. 活动A的onPause()方法执行。
  2. Activity B's onCreate() , onStart() , and onResume() methods execute in sequence. 活动B的onCreate()onStart()onResume()方法按顺序执行。 (Activity B now has user focus.) (活动B现在具有用户焦点。)
  3. Then, if Activity A is no longer visible on screen, its onStop() method executes. 然后,如果活动A在屏幕上不再可见,则执行其onStop()方法。

This predictable sequence of lifecycle callbacks allows you to manage the transition of information from one activity to another. 这种可预测的生命周期回调序列使您可以管理信息从一个活动到另一个活动的过渡。

So the behavior that you describe is expected or predictable. 因此,您描述的行为是预期的或可预测的。

Back to your questions. 回到您的问题。

1.How to completely destroy PreviousActivity when restarting an activity? 1.重新启动活动时如何完全销毁PreviousActivity?

  • Using recreate API, the limitation is it only works from API 11 or above 使用重新创建 API 的局限性在于它仅适用于API 11或更高版本

2.Is there a way to putExtras while using recreate()? 2.使用recreate()时是否有方法放置putExtras?

recreate 重建

 public void recreate () 

Cause this Activity to be recreated with a new instance. 使该活动用新实例重新创建。 This results in essentially the same flow as when the Activity is created due to a configuration change -- the current instance will go through its lifecycle to onDestroy() and a new instance then created after it. 由于配置更改,这导致与创建Activity时基本上相同的流程-当前实例将通过其生命周期进入onDestroy(),然后在其之后创建一个新实例。

Because the activity will be recreated so onSaveInstanceState and onRestoreInstanceState will be called as well. 由于将重新创建活动,因此也会调用onSaveInstanceStateonRestoreInstanceState As you can guess the idea is save data in onSaveInstanceState and retrieve in onRestoreInstanceState or onCreate . 可以猜到是将数据保存在onSaveInstanceState然后在onRestoreInstanceStateonCreate检索。

Step 1: Save data in onSaveInstanceState 步骤1:在onSaveInstanceState保存数据

// The key for saving and retrieving isActivityRecreated field.
private static final String KEY_IS_ACTIVITY_RECREATED = "KEY_IS_ACTIVITY_RECREATED";

/** true if this activity is recreated. */
private boolean isActivityRecreated = false;

// Call this method when you want to recreate this activity.
private void recreateActivity() {
    isActivityRecreated = true;
    recreate();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(KEY_IS_ACTIVITY_RECREATED, isActivityRecreated);
    outState.putInt(Constants.VIDEO_ID, videoId);
    outState.putInt(Constants.CATEGORY_ID, categoryId);
}

Step 2: Retrieve the data in onRestoreInstanceState or onCreate 步骤2:在onRestoreInstanceStateonCreate检索数据

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState != null) {
        isActivityRecreated = savedInstanceState.getBoolean(KEY_IS_ACTIVITY_RECREATED);
        if (isActivityRecreated) {
            // This activity has been recreated.
            // Reset the flag
            isActivityRecreated = false;

            // Write your code when this activity recreated.
            int videoId = savedInstanceState.getInt(Constants.VIDEO_ID);
            int categoryId = savedInstanceState.getInt(Constants.CATEGORY_ID);
            ...   
        }
    }
}

You can do it simply by setting a noHistory flag as true in AndroidManifest.xml file. 您只需在AndroidManifest.xml文件中将noHistory标志设置为true即可完成此操作。 I think you don't need to keep that activity state when minimizing according to your requirement. 我认为您可以根据需要将活动状态最小化,而无需保持该活动状态。

<activity
            android:name=".PlayerActivity"
            android:noHistory="true" />

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

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