私は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>
問題を再作成できます。
- setContentViewでブレークポイントを設定した場合、super.OnResume()で別のブレークポイントを設定します。
- デバッグビューを実行します。
- アプリをバックグラウンドに送信して、再実行します。
- 実行を終了すると、値を示すダイアログが表示されます: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