onCreate() von Activity 1 wird nach jedem startActivityForResult() neu aufgerufen

AnnaBauer21

AnnaBauer21

Neues Mitglied
2
Hallo Leute,

ich habe ein Problem mit der onCreate() Methode der Activity 1.

Ich rufe in Activity 1 durch startActivityForResult() Activity 2 auf, mache hier eine Eingabe, und liefere den Wert an Activity 1 zurück.

Bei Activity 1 wird aber die onCreate() Methode wieder neu aufgerufen.
Damit habe ich ein Problem, da ich dort eine Action bar initialisiere, in der manche Buttons deaktiviert sind und diese erst später aktiviere.

Nach dem Aufruf von startActivityForResult() wird in der onCreate() Methode die ActionBar wieder neu initialisiert und nun sind die zuvor aktivierten Buttons wieder deaktiviert.

Dieses Problem habe ich nicht im Emulator (API 16 & API 18) sondern nur auf meinem Samsung Galaxy S3 (API 18).

Bitte helft mir!

Activity 1:
Code:
public class MainActivity extends Activity implements OnClickListener {
 ...
 ActionBar actionBar;
 boolean iCheckNewState = true;  [COLOR=seagreen]//Hieran sehe ich, dass onCreate()[/COLOR] [COLOR=seagreen]immer neu durchlaufen wird[/COLOR]
 boolean iFileIsSelected = false;
 ...
 
 @Override
 [B]protected void onCreate(Bundle savedInstanceState)[/B] {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main_activity);
 
 [COLOR=seagreen] //Hier zeigt es immer true, obwohl ich die globale Variable auf false ändere[/COLOR]
[COLOR=seagreen] //Trotz erneutem Durchlauf der onCreate() sollte es hier doch false zeigen... oder?[/COLOR]
  Toast.makeText(this, "" + iCheckNewState, 1000).show();   
 
  if (iCheckNewState == true) {
   actionBar = getActionBar();
   actionBar.setCustomView(R.layout.actionbar);
   actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
 
   iCheckNewState = false;
  }
 
  ...
 }
 
 @Override
 [B]public void onClick(View v)[/B] {
  switch (v.getId()) {
  case R.id.buOK:
   [COLOR=seagreen]//Aufruf der Activity 2[/COLOR]
   Intent intent = new Intent(MainActivity.this, SelectFile.class);
   startActivityForResult(intent, 0);
   break;
  case R.id.buStart:  [COLOR=seagreen]//<-- Der deaktivierte Button der ActionBar[/COLOR]
   if (iFileIsSelected == true) {
    [COLOR=seagreen]//TODO[/COLOR]
   } else {
    Toast.makeText(this, "Öffnen sie zuerst eine Datei!", 1000).show();
   }
  }
  ...
 }
 
 @Override
 [B]protected void onActivityResult(int requestCode, int resultCode, Intent data[/B]) {
  super.onActivityResult(requestCode, resultCode, data);
 
  if (resultCode == RESULT_OK && requestCode == 0) {
   ...
   iFileIsSelected = true;   [COLOR=seagreen]//Aktivieren den Button der ActionBar[/COLOR]
  }
 }
}



Activity 2:
Code:
public class SelectFile extends Activity implements OnClickListener {
 private Intent iIntent;
 ...
 
 @Override
 [B]protected void onCreate(Bundle savedInstanceState)[/B] {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.select_file);
 
  iIntent = getIntent();
  ...
 }
 
 ...
 
 @Override
 [B]public void onClick(View v)[/B] {
  switch (v.getId()) {
  case R.id.selected:
 [COLOR=seagreen] //Daten zurück an Activity 1 geben[/COLOR]
   iIntent.putExtra("fileData", products);
   setResult(RESULT_OK, iIntent);
   finish();
   break;
  }
 }
}



Manifest:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="[URL]http://schemas.android.com/apk/res/android[/URL]"
    package="de.test"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="16" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/appicon"
        android:label="@string/app_name"
        android:screenOrientation="landscape"
        android:theme="@android:style/Theme.Holo.Light.DarkActionBar" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape" >
            <intent-filter android:label="@string/app_name" >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SelectFile"
            android:label="@string/app_name"
            android:screenOrientation="landscape" >
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>



Vielen vielen Dank schon mal im Voraus! :smile:

Liebe Grüße
Anna
 
Hey Anna Bauer

nice pic;)

Ok jetzt mal zu deinem Problem: Tja was willst du denn sonst machen? Der Lifecycle der Activities ist nun mal so da kann mann ncihts machen!

Folgendes kannst du probieren:

Prüfe ob die Activity zum ersten mal den oncreate "anwirft" das tust du indem du bundleState auf null prüfst
if (savedInstanceState==null)
//dann amche die erstinitialisierung

else
//den alten stand laden


in onPause sicherst du den State dann da dieser beim start der 2. actvity aufgerufen wird.


Hier wird es genau erklärt wie das geht!!!
 
Hallo Jaiel,

danke für deine Antwort :smile:

Ich hab mir den Link angeschaut und es funktioniert!! :thumbsup:

Vielen Dank!

Aber wegen dem LifeCycle habe ich trotzdem noch eine Frage.

Laut dem Bild hier:
lifecycle.png



Sollte die onCreate() Methode doch nur am Anfang beim erstellen der Activity aufgerufen werden. Wenn ich von der zweiten Activity wieder zu der ersten zurück komme sollte ich doch bei onResume oder zumindest bei onStart landen.

Warum ist das in meinem Fall nicht so?
Das komische ist, dass sich meine App im Emulator so wie auf dem Bild verhält, hier wird onCreate() nur einmalig durchlaufen.

Nur auf meinem Handy habe ich dieses komische Problem :unsure:
Das würde ja heißen, dass mein Handy den Prozess killt, da es zu wenig Speicher hat oder?

Liebe Grüße
Anna
 
Du siehst doch in der Grafik schön, dass mehrere Punkte zu onCreate führen.

Wenn dein Handy freien Speicher im RAM braucht, dann killt der Activities oder eben einzelne Teile, die gerade nicht aktiv sind. Deshalb steht nach "onPause", dass bei Speicherbedarf durch andere Apps (also auch Services etc. die im Hintergrund laufen) du wieder zu onCreate kommst, statt zu onResume.

Wie viel Ram hast du denn den Emulatoren gegeben? Kann also einfach sein, dass beim Galaxy S3 zu viel im Hintergrund läuft (TouchWiz etc), der ggf. viel Speicher verbraucht und dementsprechend nicht viel Spielraum ist.
 
Der Emulator hat ein RAM von 1024 wie es hier steht http://www.avd-settings.de/page/13/.
Und kann man das irgendwie sperren, dass der Prozess nicht gekillt wird, sondern vlt. erst mal alle anderen die im Hintergrund laufen?
 
Soweit ich weiß nein. (Kann mich auch täuschen, hab sowas nie machen müssen)

Mal versucht iCheckNewState mit einem static zu versehen?
 
Nein das kannst du nicht wenn dann nur mit einem gerooteten android dass du dementsprechend veränderst--->OS developing

du könntest aber einen bösen trick anwenden mit 2 services die sich gegenseitig überwachen und den jeweils anderen neu starten falls er gekillt wurde.
 
@Jaiel: wie meinst du das? Also den Punkt mit den 2 Services. Verstehe die Funktionweise noch nicht. Sehe grad nur vor meinen Augen, dass 2 Services, die sich stetig gegenseitig überwachen folgende Probleme: unnötige CPU-Last und damit Akkuverbrauch, wieder zusätzlicher Speicherverbrauch und wenn etwas neu gestartet wird, wenn etwas gekillt wird, dann sind wir wieder bei onCreate und haben nicht gekonnt?! Oder übersehe ich was?
 
ja ne eigenltich wird der prozes einfach enu gestartet also es löst ihr problem mit oncreate nicht aber der prozess wird einfach wieder neu gestartet und zwei services da ja ein service auch jederzeit gekillt werden kann :D
also eigentlich ist meine antwort nicht richtig weil man den kill nciht verhindern kann sorry:flapper:
 
Ohje :lol:

Da hab ich mir mal wieder ein schönes Problem ausgesucht! :rolleyes2:

Aber danke euch beiden!

@Jaiel
Deine 1. Antwort funktioniert so wie ich es benötigt!
Ich muss halt leider jeden Variablenstatus den ich verändert habe und nach dem erneuten onCreate() noch benötige separat abspeichern aber ist halb so schlimm ;)

Vielen Dank!
 
Das ist ganz normal, dass Activities, die im Hintergrund sind auch mal beendet werden. Genauso wird eine Activity komplett neugestartet (kompletter Lifecycle inklusive onCreate) wenn du das Gerät ins Querformat oder Hochformat drehst.

Deshalb muss man eventuellen State den man braucht auch speichern und wiederherstellen.

Dafür gibt es in der Actibity onSaveInstanceState. Die kannst du überschreiben und alles was du beim nächsten Start wiederhaben willst in das mitgegebene Bundle liefern.
Das Bundle kommt dann in der onCreate als savedInstanceState wieder mit. Und dort machst du dann wie erwähnt eine null Prüfung und wenn der State vorhanden ist kannst du deine Werte wieder aus dem Bundle rausholen und anwenden.

Das ist so die gängige Praxis.

@reneph: Da es durchauch mehrere Instanzen einer Activity geben kann sollte man keinen State in eine statische Variable schreiben.
 
  • Danke
Reaktionen: reneph

Ähnliche Themen

5
Antworten
22
Aufrufe
1.421
590239
5
M
  • MikelKatzengreis
Antworten
10
Aufrufe
225
swa00
swa00
Zurück
Oben Unten