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

Ale*_*Bcn 6 android google-maps android-emulator

我正在开发一个Android应用程序,在我使用MapsActivity来显示Map的其中一个活动中.我所看到的是,在2.2(API8)模拟器上加载地图需要一些时间,我有时间按下菜单按钮,然后回到应用程序,它仍然在setContentView()上加载,问题当它转到onResume()时会被调用两次.

根据Android活动的生命周期,在onPause() - > [onRestart() - > onStart()] - > onResume()之后,如果应用程序再次到达前台,则会调用onResume()在启动时在onCreate() - > [onStart()]之后调用.

但是如果它仍然在onCreate()的setContentView上加载,为什么不调用一次?

这是我感兴趣的东西,因为每次我使用地图时都不想使用布尔值,认为可以执行两次以避免出现问题,即计数器的双增量.

我不知道这是模拟器的问题,因为我看到的关于横向纵向方向的问题http://code.google.com/p/android/issues/detail?id=2423.

请看看这个:

  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;
   }
  }
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

您可以重新创建问题:

  1. 如果在setContentView中设置断点,则在super.OnResume()处设置另一个断点.
  2. 执行和调试视图时.
  3. 将应用程序发送到后台并重新运行它.
  4. 完成执行后,您应该看到一个显示值的对话框:2.


阅读Geobits和G. Blake Meike所做的评论,这部分是一个答案,只是为了澄清我是否错了.

也许由于地图的异步负载,地图的例子很糟糕.我更改了一个Activity的MapsActivity,让我们假设手机过载了,所以onCreate会执行一个8秒的循环(不是Android Not Responding的时间).

这里使用轻量级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));
}
}
Run Code Online (Sandbox Code Playgroud)

如果我在日志仍在打印"睡觉..."时最小化应用程序并且很快我重新运行应用程序我可以看到"正在睡觉...",onResume将检查两次连接(这是一种正确的方式检查网络连接).

这里是logCat:

  • 2-28 20:02:48.643:W/LocationActivity(651):onCreate
  • 2-28 20:02:48.646:W/LocationActivity(651):beforeLoop
  • 02-28 20:02:48.646:W/LocationActivity(651):睡觉......
  • 02-28 20:02:49.655:W/LocationActivity(651):睡觉......
  • 02-28 20:02:50.678:W/LocationActivity(651):睡觉......
  • 02-28 20:02:51.673:W/LocationActivity(651):睡觉......
  • 02-28 20:02:52.674:W/LocationActivity(651):睡觉......
  • 02-28 20:02:53.738:W/LocationActivity(651):睡觉......
  • 02-28 20:02:54.773:W/LocationActivity(651):睡觉......
  • 02-28 20:02:55.795:W/LocationActivity(651):睡觉......
  • 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):检查移动连接
  • 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.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):检查移动连接
  • 02-28 20:02:57.324:W/LocationActivity(651):showsToast

Toast将显示两次消息.

查看logCat生命周期是正确的,但我只想考虑到有时onCreate可能因为系统过载而延迟,如果onResume被执行两次,那么我必须处理一些初始化,所以我必须使用布尔值我认为我不应该使用,因为onCreate仍在运行.

如果不是Toast它是一个对话框,则从用户的POV中不欢迎两个对话框.

请以与我相同的方式执行代码,我很顽固,不能放弃:P

Geo*_*its 5

这是设计的.如果将活动发送到后台,则必须onResume()在返回时调用.

文档:

请注意,每当您的活动进入前台时系统都会调用此方法,包括第一次创建活动时.因此,您应该实现onResume()来初始化在onPause()期间释放的组件,并执行每次活动进入Resumed状态时必须发生的任何其他初始化(例如,开始动画和初始化仅在活动具有用户时使用的组件)焦点).

还要注意,setContentView()可能已经回来了.它不应该花很长时间,即使是一个MapView.地图可能是异步加载的,因此它不会占用UI线程.