简体   繁体   English

如果应用程序仍在运行onCreate方法,为什么onResume方法将被执行两次?

[英]Why the method onResume is going to be executed twice if the app is still running the onCreate method?

I am developping an Android app and in one of the activities I am using the MapsActivity to show a Map. 我正在开发一个Android应用程序,在我使用MapsActivity来显示Map的其中一个活动中。 What I have seen is that on an 2.2 (API8) emulator it takes some time to load the map and I have time to press the menu button and then come back to the app and it is still loading on the setContentView(), the problem comes when it goes to onResume() which is gonna be called twice. 我所看到的是,在2.2(API8)模拟器上加载地图需要一些时间,我有时间按下菜单按钮,然后回到应用程序,它仍然在setContentView()上加载,问题当它转到onResume()时会被调用两次。

According to the lifecycle of an Android activity, after a onPause()->[onRestart()-->onStart()]-->onResume() is gonna be called if the app comes to the foreground again, and onResume() is called after onCreate()->[onStart()] when is launched. 根据Android活动的生命周期,在onPause() - > [onRestart() - > onStart()] - > onResume()之后,如果应用程序再次到达前台,则会调用onResume()在启动时在onCreate() - > [onStart()]之后调用。

But why is not called once if the it is still loading on setContentView in onCreate() ? 但是如果它仍然在onCreate()的setContentView上加载,为什么不调用一次?

This is something that interest me because I would not like to use a boolean each time I use maps thinking that it could be executed twice to avoid problems, ie a double incrementation of a counter. 这是我感兴趣的东西,因为每次我使用地图时都不想使用布尔值,认为可以执行两次以避免出现问题,即计数器的双增量。

I do not know if it is a problem of the emulator as the issue I have seen about landscape-portrait orientation http://code.google.com/p/android/issues/detail?id=2423 . 我不知道这是模拟器的问题,因为我看到的关于横向纵向方向的问题http://code.google.com/p/android/issues/detail?id=2423

Please take a look at this: 请看看这个:

  public class LocationActivity extends MapActivity {

    private static final String TAG = "LocationActivity";
    private static int i;

    protected void onCreate(Bundle savedInstanceState) {
       i = 0;
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_location);
    }

    protected void onResume(){
       super.onResume();    
       i++;
       Log.w(TAG,String.valueOf(i));           
       showDialogSettings();
    }

    private void showDialogSettings() {

      AlertDialog.Builder dialog = new AlertDialog.Builder(this);
      String title = "I-Value:" + String.valueOf(i);
      String positiveButton = "OK";
      final Intent intent = new Intent(Settings.ACTION_SETTINGS);

      dialog.setTitle(title);
      dialog.setPositiveButton(positiveButton, new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {   
            Intent settingsIntent = intent;
           startActivity(settingsIntent);
         }
      });
      dialog.show();
   }

   @Override
   protected boolean isRouteDisplayed() {
      return false;
   }
  }

activity_location.xml activity_location.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <com.google.android.maps.MapView
            android:id="@+id/locationactivity"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:apiKey="XXXXXXXXXXXXXXX"
            android:clickable="false"
            android:enabled="true" />

    </LinearLayout>

You can re-create the issue: 您可以重新创建问题:

  1. If you set a breakpoint at setContentView an another one at super.OnResume(). 如果在setContentView中设置断点,则在super.OnResume()处设置另一个断点。
  2. Execute and when the debug view. 执行和调试视图时。
  3. Send to background the app and re-run it again. 将应用程序发送到后台并重新运行它。
  4. Finish the execution , you should see a dialog showing a value:2. 完成执行后,您应该看到一个显示值的对话框:2。


Read the comments done by Geobits and G. Blake Meike, this part is an answer just to clarify if I am wrong. 阅读Geobits和G. Blake Meike所做的评论,这部分是一个答案,只是为了澄清我是否错了。

Maybe the example with maps was a bad one because of the asyncronous load of the map. 也许由于地图的异步负载,地图的例子很糟糕。 I changed the MapsActivity for an Activity, let's suppose that the phone is overloaded, so onCreate is gonna execute a loop of 8 seconds (not enougth time for an Android Not Responding). 我更改了一个Activity的MapsActivity,让我们假设手机过载了,所以onCreate会执行一个8秒的循环(不是Android Not Responding的时间)。

And here the new code using a light android layout: 这里使用轻量级Android布局的新代码:

 public class LocationActivity extends Activity {

private static final String TAG = "LocationActivity";
private static int i;

protected void onCreate(Bundle savedInstanceState) {
    i = 0;
    Log.w(TAG,"onCreate");
    super.onCreate(savedInstanceState);
    setContentView(android.R.layout.simple_spinner_item);
    Log.w(TAG,"beforeLoop");
    try {
        for(int j = 0; j < 8; j++){
            Log.w(TAG,"Sleeping...");
            Thread.sleep(1000);
        }
    } catch (InterruptedException e) {
    }
    Log.w(TAG,"afterLoop");
}

protected void onResume(){
    super.onResume();
    Log.w(TAG,"onResume" + String.valueOf(i));
    i++;
    Log.w(TAG,"check Mobile Connectivity");     
    ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();       
    if(networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE && networkInfo.isAvailable()){
        Toast.makeText(this, "Network available!", Toast.LENGTH_LONG).show();
        Log.w(TAG,"showingToast");
    }

}

protected void onPause(){
    super.onPause();
    Log.w(TAG,"onPause:" + String.valueOf(i));
}

protected void onStop(){
    super.onResume();
    Log.w(TAG,"onStop:" + String.valueOf(i));
}
}

If I minimize the app when the log is still printing "Sleeping..." and quickly I re-run the app I can see the "Sleeping...", onResume will check two times the Connectivity (this is a correct way of checking the network connectivity). 如果我在日志仍在打印“睡觉...”时最小化应用程序并且很快我重新运行应用程序我可以看到“正在睡觉...”,onResume将检查两次连接(这是一种正确的方式检查网络连接)。

Here goes the logCat: 这里是logCat:

  • 2-28 20:02:48.643: W/LocationActivity(651): onCreate 2-28 20:02:48.643:W / LocationActivity(651):onCreate
  • 2-28 20:02:48.646: W/LocationActivity(651): beforeLoop 2-28 20:02:48.646:W / LocationActivity(651):beforeLoop
  • 02-28 20:02:48.646: W/LocationActivity(651): Sleeping... 02-28 20:02:48.646:W / LocationActivity(651):睡觉......
  • 02-28 20:02:49.655: W/LocationActivity(651): Sleeping... 02-28 20:02:49.655:W / LocationActivity(651):睡觉......
  • 02-28 20:02:50.678: W/LocationActivity(651): Sleeping... 02-28 20:02:50.678:W / LocationActivity(651):睡觉......
  • 02-28 20:02:51.673: W/LocationActivity(651): Sleeping... 02-28 20:02:51.673:W / LocationActivity(651):睡觉......
  • 02-28 20:02:52.674: W/LocationActivity(651): Sleeping... 02-28 20:02:52.674:W / LocationActivity(651):睡觉......
  • 02-28 20:02:53.738: W/LocationActivity(651): Sleeping... 02-28 20:02:53.738:W / LocationActivity(651):睡觉......
  • 02-28 20:02:54.773: W/LocationActivity(651): Sleeping... 02-28 20:02:54.773:W / LocationActivity(651):睡觉......
  • 02-28 20:02:55.795: W/LocationActivity(651): Sleeping... 02-28 20:02:55.795:W / LocationActivity(651):睡觉......
  • 02-28 20:02:56.816: W/LocationActivity(651): afterLoop 02-28 20:02:56.816:W / LocationActivity(651):afterLoop
  • 02-28 20:02:56.824: W/LocationActivity(651): onResume0 02-28 20:02:56.824:W / LocationActivity(651):onResume0
  • 02-28 20:02:56.824: W/LocationActivity(651): check Mobile Connectivity 02-28 20:02:56.824:W / LocationActivity(651):检查移动连接
  • 02-28 20:02:57.134: W/LocationActivity(651): showingToast 02-28 20:02:57.134:W / LocationActivity(651):showsToast
  • 02-28 20:02:57.234: W/LocationActivity(651): onPause:1 02-28 20:02:57.234:W / LocationActivity(651):onPause:1
  • 02-28 20:02:57.253: W/LocationActivity(651): onStop:1 02-28 20:02:57.253:W / LocationActivity(651):onStop:1
  • 02-28 20:02:57.264: W/LocationActivity(651): onResume1 02-28 20:02:57.264:W / LocationActivity(651):onResume1
  • 02-28 20:02:57.264: W/LocationActivity(651): check Mobile Connectivity 02-28 20:02:57.264:W / LocationActivity(651):检查移动连接
  • 02-28 20:02:57.324: W/LocationActivity(651): showingToast 02-28 20:02:57.324:W / LocationActivity(651):showsToast

Toast will show two times the message. Toast将显示两次消息。

Looking at the logCat the lifecycle is correct, but I just want to take into consideration that sometimes onCreate could be delayed because of an overloaded system and if onResume is executed twice then I have to take care of some initializations, so I have to use booleans which I consider I should not use because the onCreate was still running. 查看logCat生命周期是正确的,但我只想考虑到有时onCreate可能因为系统过载而延迟,如果onResume被执行两次,那么我必须处理一些初始化,所以我必须使用布尔值我认为我不应该使用,因为onCreate仍在运行。

If instead of a Toast it is a dialog, from the POV of the user two dialogs are not welcome. 如果不是Toast它是一个对话框,则从用户的POV中不欢迎两个对话框。

Please execute the code in the same way as I do, I am stubborn enough to not give up :P 请以与我相同的方式执行代码,我很顽固,不能放弃:P

This is by design. 这是设计的。 If you send the activity to background, it must call onResume() when it returns. 如果将活动发送到后台,则必须在返回时调用onResume()

From the documentation : 文档

Be aware that the system calls this method every time your activity comes into the foreground, including when it's created for the first time. 请注意,每当您的活动进入前台时系统都会调用此方法,包括第一次创建活动时。 As such, you should implement onResume() to initialize components that you release during onPause() and perform any other initializations that must occur each time the activity enters the Resumed state (such as begin animations and initialize components only used while the activity has user focus). 因此,您应该实现onResume()来初始化您在onPause()期间释放的组件,并执行每次活动进入Resumed状态时必须发生的任何其他初始化(例如开始动画和初始化仅在活动具有用户时使用的组件)焦点)。

Also note, setContentView() has probably already returned. 另请注意, setContentView()可能已经返回。 It shouldn't take long, even for a MapView . 它不应该花很长时间,即使对于MapView The map is probably loaded asynchronously, so it doesn't tie up the UI thread. 地图可能是异步加载的,因此它不会占用UI线程。

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

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