2013-02-28 7 views
6

私はAndroidアプリを開発しています。私はMapsActivityを使って地図を表示しています。 私が見たことは、2.2(API8)エミュレータで地図を読み込むのに時間がかかることです。メニューボタンを押してからアプリに戻ってきて、まだsetContentView()、それが2回呼び出されるonResume()に行くと問題が発生します。なぜアプリケーションがonCreateメソッドを実行している場合、メソッドonResumeが2回実行されるのですか?

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 ANにブレークポイントを設定した場合もう1つはsuper.OnResume()です。
  2. デバッグビューを実行するときと実行します。
  3. アプリをバックグラウンドで送信し、もう一度アプリを再実行します。
  4. 実行を終了すると、値を示すダイアログが表示されます。


GeobitsとG.ブレイクMeikeによって行われたコメントを読んで、この部分は私が間違っている場合だけで明確にする答えです。

地図の非同期的な読み込みのため、地図の例が悪い場合があります。 アクティビティの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 ..."の場合、onResumeはコネクティビティを2回確認します(これはネットワーク接続をチェックする正しい方法です)。ここで

はlogCatを行く:

  • 2-28 20時02分48秒。643:W/LocationActivity(651)のonCreate
  • 2-28 20:02:48.646:LocationActivity/W(651):beforeLoop
  • 2月28日20:02:48.646:W/LocationActivity(651):眠ります...
  • 2月28日20:02:49.655:W/LocationActivity(651):眠る...
  • 2月28日20:02:50.678:LocationActivity/W(651):...
  • スリーピング02:
  • 02から28 20 51.673:LocationActivity/W(651):眠る...
  • 2月28日20:02:52.674:W/LocationActivity(651):眠る...
  • 02- 28 20:02:53.738:W/LocationAct (651):睡眠...
  • 02-28 20:02 54.773:睡眠...
  • 02-28 20:02:55.795:W/LocationActivity(651) :スリーピング...
  • 2月28日20:02:56.816:W/LocationActivity(651):W/LocationActivity(651):afterLoop
  • 2月28日20:02:56.824 onResume0
  • 02- 28 20:02:56.824:LocationActivity/W(651):チェックモバイル接続
  • 2月28日20:02:57.134:LocationActivity/W(651):showingToast
  • 2月28日20:02:57.234:W/LocationActiv ITY(651):onPause:1
  • 2月28日20:02:57.253:/ LocationActivity(651)W:onStop:1
  • 2月28日20:02:57.264:/ LocationActivity(651)W:onResume1
  • 2月28日20:02:57.264:W/LocationActivity(651):モバイル接続を確認
  • 2月28日20:02:57.324:W/LocationActivity(651):showingToast

トースト意志メッセージを2回表示する。

logCatのライフサイクルは正しいですが、オーバーロードされたシステムのためにonCreateが遅れることがあり、onResumeが2回実行された場合、初期化に注意する必要があることを考慮したいと思いますonCreateがまだ動作していたので私が使用すべきではないと考えるブーリアンを使用する必要があります。

Toastの代わりにダイアログである場合、ユーザーのPOVから2つのダイアログを歓迎しません。

私がそうであるように同じ方法でコードを実行してください、私はあきらめていないのに十分な頑固だ:P

+0

onCreateを実行してからonResumeを実行するスレッドが1つあります。 onCreateが返るまで、onResumeを呼び出すことはできません。大量のイベントをキューに入れると、onCreateが終了したときに順番にイベントが発生します。 Androidはまさにあなたが言ったことを行いました。起動するたびにダイアログを表示します。あなたはそれを二度始める。そして、btw、8秒はANRを引き起こすのに十分な長さです。 –

+0

今、私はそれを得る、ありがとう。 – AlexBcn

答えて

5

これは仕様によるものです。活動をバックグラウンドに送信する場合は、となります。返信する場合はonResume()としてください。 the documentationから

は、システムは、それが初めて作成だときなど、この方法であなたのアクティビティがフォアグラウンドに入ってくるたびに呼び出すことに注意してください。したがって、onPause()中に解放したコンポーネントを初期化し、アクティビティがResumed状態になるたびに発生する必要があるその他の初期化を実行するには、onResume()を実装する必要があります(アニメーションの開始や、フォーカス)。

また、setContentView()はすでに返されている可能性があります。 MapViewの場合でも、時間がかかりません。マップはおそらく非同期にロードされるため、UIスレッドを結び付けません。

+0

こんにちは@Geobitsはいあなたが言うことはすべて正しいですが、私が言及した手順に従えば、ダブルコールが表示されます。 setContentViewでブレークポイントを設定し、アクティビティをフォアグラウンドにすると、システムはそれを検出し、実行を再開した後にonResumeを一度呼び出す必要があります。 Witoutのデバッグが発生します。私のラップトップは、マップをsetContentViewに渡すのに約15秒かかって、アプリケーションを最小限に抑えて再実行し、突然値2のダイアログが表示されます。 – AlexBcn

+0

@AlexBcn:Geobitsは正確に正しいです。ビューの内容が完全に表示されていないため、setContentViewが返されていないと考えられます。それは本当ではありません!そのように働くと、マップをロードするたびにANRが得られます。あなたのアプリは一時停止され、正しく再開されました。地図の読み込みは非同期的に起こり、あなたのアプリはonCreateに*まだ*ありません。 –

+0

こんにちは@G。 Blake Meike、質問にテキストを追加しました。チェックしてください。ありがとう。 – AlexBcn

関連する問題