Ich entwickle eine Android App und in einer der Aktivitäten verwende ich die MapsActivity um eine Map zu zeigen. Was ich gesehen habe, ist, dass es auf einem 2.2 (API8) Emulator einige Zeit dauert, um die Karte zu laden und ich habe Zeit, die Menüschaltfläche zu drücken und dann wieder auf die appContentView() zu laden Problem kommt, wenn es auf onResume() geht, die zweimal aufgerufen wird.Warum wird die Methode onResume zweimal ausgeführt, wenn die App noch die onCreate-Methode ausführt?
Je nach Lebenszyklus einer Android-Aktivität wird nach einem onPause() -> [onRestart() -> onStart()] -> onResume() aufgerufen, wenn die App wieder in den Vordergrund kommt, und onResume() wird nach onCreate() -> [onStart()] aufgerufen, wenn es gestartet wird.
Aber warum wird nicht einmal aufgerufen, wenn es noch in setContentView in onCreate() geladen wird?
Das ist etwas, das mich interessiert, weil ich nicht jedes Mal ein boolean verwenden möchte, wenn ich Karten verwende, die denken, dass es zweimal ausgeführt werden könnte, um Probleme zu vermeiden, d. H. Eine doppelte Inkrementierung eines Zählers.
Ich weiß nicht, ob es ein Problem des Emulators ist, wie das Problem, das ich über Querformatausrichtung http://code.google.com/p/android/issues/detail?id=2423 gesehen habe.
Bitte nehmen Sie sich einen Blick auf diese:
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>
Sie können das Problem neu erstellen:
- Wenn Sie einen Haltepunkt an setContentView ein Set ein weiterer bei super.OnResume().
- Ausführen und wenn die Debug-Ansicht.
- Senden Sie die App an den Hintergrund und führen Sie sie erneut aus.
- Beenden Sie die Ausführung, Sie sollten einen Dialog sehen, der einen Wert anzeigt: 2.
die Kommentare von Geobits und G. Blake Meike getan lesen, ist dieser Teil eine Antwort nur zu klären, wenn ich falsch bin.
Vielleicht war das Beispiel mit Karten wegen der asynchronen Belastung der Karte schlecht. Ich habe die MapsActivity für eine Aktivität geändert. Nehmen wir an, dass das Telefon überlastet ist. OnCreate führt also eine Schleife von 8 Sekunden aus (nicht genug Zeit für ein Android, das nicht antwortet).
Und hier der neue Code ein Licht android Layout mit:
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));
}
}
Wenn ich die Anwendung minimiert, wenn das Protokoll nach wie vor „Sleeping ...“ druckt und schnell ich die app ich sehen kann wieder laufen das "Sleeping ...", überprüft onResume zweimal die Konnektivität (dies ist eine korrekte Art der Überprüfung der Netzwerkkonnektivität).
geht hier die 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): Schlafen ...
- 02-28 20: 02: 49,655: W/LocationActivity (651): Schlafen ...
- 02-28 20: 02: 50,678: W/LocationActivity (651): Schlafen ...
- 02-28 20: 02: 51,673: W/LocationActivity (651): Schlafen ...
- 02-28 20: 02: 52,674: W/LocationActivity (651): Schlafen ...
- 02- 28 20: 02: 53.738: W/StandortAkt ivity (651): Schlafen ...
- 02-28 20: 02: 54,773: W/LocationActivity (651): Schlafen ...
- 02-28 20: 02: 55,795: W/LocationActivity (651) Schlafen ...
- 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): check Mobil Connectivity
- 02-28 20: 02: 57,134: W/LocationActivity (651): showingToast
- 02-28 20: 02: 57,234: W/StandortActiv ity (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): Check mobile Connectivity-
- 02-28 20: 02: 57,324: W/LocationActivity (651): showingToast
Toast wird Zeige zweimal die Nachricht.
Mit Blick auf die logCat ist der Lebenszyklus korrekt, aber ich möchte nur berücksichtigen, dass onCreate manchmal wegen eines überlasteten Systems verzögert werden kann und wenn onResume zweimal ausgeführt wird, dann muss ich mich um einige Initialisierungen kümmern, also ich Ich muss Booleans verwenden, die ich nicht benutzen sollte, weil onCreate noch läuft.
Wenn es sich bei einem Toast um einen Dialog handelt, sind aus dem POV des Benutzers zwei Dialoge nicht erwünscht.
Bitte führen Sie den Code in der gleichen Art und Weise wie ich, bin ich stur genug, um nicht bis geben: P
Es gibt einen einzelnen Thread, der OnCreate und onResume ausführt. Bis OnCreate zurückkehrt, kann onResume nicht aufgerufen werden. Wenn Sie eine Reihe von Ereignissen in die Warteschlange stellen, werden sie der Reihe nach ausgeführt, wenn onCreate beendet wird. Android hat genau das getan, was Sie ihm gesagt haben: Jedes Mal, wenn es startet, einen Dialog erstellen. Du hast es zweimal angefangen. Und, btw, 8 Sekunden ist * way * lang genug, um eine ANR zu verursachen ... –
Ok jetzt bekomme ich es, danke allen. – AlexBcn