6

私はAndroidアプリを開発しており、アクティビティの1つで、MapsActivityを使用して地図を表示しています。私が見たのは、2.2(API8)エミュレーターでは、マップのロードに時間がかかり、メニューボタンを押してからアプリに戻っても、setContentView()にロードされているという問題です。 2回呼び出されるonResume()に行くと来る。

Androidアクティビティのライフサイクルによると、onPause()-> [onRestart()-> onStart()]-> onResume()が呼び出された後、アプリが再びフォアグラウンドになり、onResume()が呼び出されます。起動時にonCreate()-> [onStart()]の後に呼び出されます。

しかし、onCreate()のsetContentViewにまだロードされているのに、なぜ一度も呼び出されないのでしょうか。

これは、問題を回避するために2回実行できると考えて、マップを使用するたびにブール値を使用したくないので、私が興味を持っていることです。つまり、カウンターの2回のインクリメントです。

横向きのポートレートの向きについて見た問題として、エミュレータの問題かどうかはわかりません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;
   }
  }

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>

問題を再作成できます。

  1. setContentViewでブレークポイントを設定した場合、super.OnResume()で別のブレークポイントを設定します。
  2. デバッグビューを実行します。
  3. アプリをバックグラウンドに送信して、再実行します。
  4. 実行を終了すると、値を示すダイアログが表示されます:2。


GeobitsとG.BlakeMeikeによるコメントを読んでください。この部分は、私が間違っているかどうかを明確にするための答えです。

マップの負荷が非同期であるため、マップを使用した例は悪い例だったのかもしれません。アクティビティのMapsActivityを変更しました。電話が過負荷になっていると仮定すると、onCreateは8秒のループを実行します(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));
}
}

ログに「Sleeping...」と表示されているときにアプリを最小化し、すぐにアプリを再実行すると、「Sleeping ...」が表示されます。onResumeは接続性を2回チェックします(これは正しい方法です。ネットワーク接続の確認)。

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):showingToast
  • 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):showingToast

トーストはメッセージを2回表示します。

logCatのライフサイクルは正しいですが、システムの過負荷が原因でonCreateが遅延する場合があり、onResumeが2回実行されると、初期化を行う必要があるため、ブール値を使用する必要があることを考慮に入れたいと思います。 onCreateがまだ実行されていたので、使用すべきではないと思います。

トーストの代わりにダイアログである場合、ユーザーのPOVから2つのダイアログは歓迎されません。

私と同じようにコードを実行してください、私はあきらめないほど頑固です:P

4

1 に答える 1

5

これは仕様によるものです。アクティビティをバックグラウンドに送信する場合は、戻ったときに呼び出す必要onResume()があります。

ドキュメントから:

初めて作成されたときを含め、アクティビティがフォアグラウンドに入るたびに、システムがこのメソッドを呼び出すことに注意してください。そのため、onResume()を実装して、onPause()中にリリースするコンポーネントを初期化し、アクティビティが再開状態になるたびに発生する必要があるその他の初期化を実行する必要があります(アニメーションの開始や、アクティビティにユーザーがいる場合にのみ使用されるコンポーネントの初期化など)。集中)。

setContentView()また、おそらくすでに戻っていることに注意してください。でも、それほど時間はかからないはずMapViewです。マップはおそらく非同期でロードされるため、UIスレッドを拘束することはありません。

于 2013-02-28T16:58:40.453 に答える