Activities und ihre Methoden

  • 27 Antworten
  • Letztes Antwortdatum
A

Andrawit

Neues Mitglied
0
Hallo,

ich bin derzeit dabei mir eine App zu bauen bei der man über den Menüknopf ein Menü öffnet und dann auf "Einstellungen" zu einer Seite gelangen kann, in der man für die App nötige Informationen ändern kann. In diesem Fall ist es eine Nummer. Die Hauptseite und die Einstellungs-Seite habe ich bisher in jeweils ein Layout und eine Activity gepackt. Das Grundgerüst steht auch alles soweit und fuktioniert. Das Problem sind aber einfach diese blöden Activities :mad:
Es soll natürlich so sein, dass ich auf die Einstellungs-Activity gehe, dort die Nummer ändere und wieder zurück zur Hauptseite gehe. Wenn ich dann erneut unter Einstellungen gehe, SOLLTE die Nummer dann natürlich noch da stehen. Tut sie aber nicht. Anscheinend macht Android mir jedes mal eine komplett neue Activity mit Standard-Einstellungen.

Um mal ganz langsam Licht ins Dunkel zu bringen:

Habe mir daraufhin was im Netz zum Thema Activities gesucht und folgendes gefunden: Googles Android/ Activities

Im Unterkapitel "Das Leben einer Activity" steht was von den ganzen Methoden onCreate, onPause, etc... um das ganze mal zu testen (wie es dort auch steht) habe ich mir zwei Activitys gebastelt mit je 1 Button und 1 TextView.

MainActivity:
Code:
package com.example.testactivities;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import android.app.Activity;
import android.content.Intent;
public class MainActivity extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) 
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);  
  Toast.makeText(getBaseContext(), "onCreate Main-Activity", Toast.LENGTH_SHORT).show();
 }
 
 @Override
 protected void onStart()
 {  
  super.onStart();
  Toast.makeText(getBaseContext(),"onStart Main-Activity", Toast.LENGTH_SHORT).show();
 }
 
 @Override
 protected void onRestart()
 {
  super.onRestart();
  Toast.makeText(getBaseContext(),"onRestart Main-Activity", Toast.LENGTH_SHORT).show();
 }
 
 @Override
 protected void onResume()
 {
  super.onResume();   
  Toast.makeText(getBaseContext(), "onResume Main-Activity", Toast.LENGTH_SHORT).show();
 } 
 
 @Override
 protected void onPause()
 {
  super.onPause();
  Toast.makeText(getBaseContext(), "onPause Main-Activity", Toast.LENGTH_SHORT).show();
 }
 
 @Override
 protected void onStop()
 {
  super.onStop();
  Toast.makeText(getBaseContext(), "onStop Main-Activity", Toast.LENGTH_SHORT).show();
 }
 
 @Override
 protected void onDestroy()
 {  
  Toast.makeText(getBaseContext(), "onDestroy Main-Activity", Toast.LENGTH_SHORT).show();
  super.onDestroy();
 }
 
 public boolean ButtonClick(View v)
 {
  Intent intet = new Intent(this, SecondActivity.class);
  startActivityForResult(intet, 0);
  
  return true;
 }
}

Activity Zwei:
Code:
package com.example.testactivities;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class SecondActivity extends Activity
 {
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_zwei);
   Toast.makeText(getBaseContext(), "onCreate Activity Zwei", Toast.LENGTH_SHORT).show();
  }
  
  @Override
  protected void onStart()
  {
   super.onStart();
   Toast.makeText(getBaseContext(), "onStart Activity Zwei", Toast.LENGTH_SHORT).show();
  }
  
  @Override
  protected void onRestart()
  {
   super.onRestart();
   Toast.makeText(getBaseContext(), "onRestart Activity Zwei", Toast.LENGTH_SHORT).show();
  }
  
  @Override
  protected void onResume()
  {
   super.onResume();
   Toast.makeText(getBaseContext(), "onResume Activity Zwei", Toast.LENGTH_SHORT).show();
  } 
  
  @Override
  protected void onPause()
  {
   this.onPause();   
   Toast.makeText(getBaseContext(),"onPause Activity Zwei", Toast.LENGTH_SHORT).show();
  }
  
  @Override
  protected void onStop()
  {
   super.onStop();
   Toast.makeText(getBaseContext(), "onStop Activity Zwei", Toast.LENGTH_SHORT).show();
  }
  
  @Override
  protected void onDestroy()
  {
   super.onDestroy();
   Toast.makeText(getBaseContext(), "onDestroy Activity Zwei", Toast.LENGTH_SHORT).show();
  }
  
  public boolean ButtonClick(View v)
  {
   onPause();
   return true;
  }
 }

Wenn ich jetzt die App starte ruft er direkt onCreate (logisch) auf... allerdings bleibts dabei nicht. Ebenfalls wird aufgerufen onStart, onRestart und onResume. Aber WARUM?

Eigentlcih sollte er doch hier nur onCreate aufrufen?!

Hoffe ihr könnt mir in etwa folgen.

MfG
 
Hi,

das ist schon alles richtig so ;)
Denke hier bist du besser aufgehoben.
Die angehängte Grafik zeigt dir den kompletten Aufbaue einer Activity. Wann was passiert... Warum das so abläuft, steht im verlinkten Artikel ;)

Um zu deinem grunsätzlichen problem zu kommen:
Du musst natürlich deine Zahl irgendwo speichern und entsprechend wieder "laden".

Gruß
 

Anhänge

  • activity_lifecycle.png
    activity_lifecycle.png
    14,6 KB · Aufrufe: 357
Hi,

danke für deine rasche Antwort. Dann werde ich mir das mal durchlesen und hoffentlich verstehen.

Also zu meiner App: Ich rufe die App jedes mal über startActivityForResult(); auf. Was mich dann nur wundert, dass jedes mal die Methode onCreate aufgerufen wird und eine kompeltt neue Activity erstellt wird.
Ist das erneute Aufrufen über startActivityForResult(); denn überhaupt der richtige Weg? Oder gibt es eine andere Methode, dass ich ihm sagen muss: "Hole mir die bereits erstellte Activity wieder nach vorn"?

MfG
 
Lies dir die Dokumentation durch. Glaube da wird es behandelt ;)
startActvityi(); reicht normalerweise schon.

Und was ich nicht ganz verstehe:
Ist das erneute Aufrufen über startActivityForResult(); denn überhaupt der richtige Weg? Oder gibt es eine andere Methode, dass ich ihm sagen muss: "Hole mir die bereits erstellte Activity wieder nach vorn"?
Was willst du genau machen? Wenn du über das Overflow-Menü die Settings-Activity öffnest, machst du das mit startActivity(). Wenn du nun wieder zurück willst, benutzt du deinen zurück buttom am handy. Du musst dich also nicht von selbst drum kümmern, dass er zu der "MAin" Activity zurückkehrt..

Gruß
 
Schau dir SharedPreferences an. Speicher dort deinen Wert und hol ihn auch immer dort wieder beim Erstellen deiner Activity ab :)
 
StefMa schrieb:
Und was ich nicht ganz verstehe:

Was willst du genau machen? Wenn du über das Overflow-Menü die Settings-Activity öffnest, machst du das mit startActivity(). Wenn du nun wieder zurück willst, benutzt du deinen zurück buttom am handy. Du musst dich also nicht von selbst drum kümmern, dass er zu der "MAin" Activity zurückkehrt..

Gruß

Ja richtig. Aber ich meine, wenn ich über den ZurückButton wieder auf die Main-Activitiy bin, dann wird die Settings-Activity vermutlich ja nicht komplett geschlossen, sondern nur in den Hintergrund gestellt - so wie ich das verstanden habe. Wenn ich jetzt erneut den Menü-Button drücke und darüber in die Einstellungen gelange, wird die Methode onCreate aufgerufen (habe zur Überprüfung ein Toast eingefügt). Das heißt: Die Settings-Activity wird komplett neu erstellt, obwohl ich die Einstellungen vorher bereits aufgerufen hatte. Je öfter ich also die Einstellungen öffne, desto mehr Setting-Activities habe ich. Daher meine Frage: Wie kriege ich es hin, dass er auf die bereits existierende zugreift und keine zweite, dritte, ..., n-te Activity erstellt?

Wenn ich in der Settings-Activity den Zurück-Button am Handy drücke, wird die onCreate-Methode nämlich anscheinend nicht aufgerufen.

Ich hoffe ich bring hier jetzt nicht alles durcheinader :blink::huh:
 
Jain - nicht direkt :)
Aber du hast ein ganz anderes problem. Du machst dir grade eins, wo keins ist :D

Wie nämnlich schon klenerKathe geschrieben hat:
Du musst dir einfach deinen Wert irgendwo speichern. In dem fall sind SharedPreferences geeignet. Dann in der onCreate musst du jeweils sagen "ist wert vorhanden -> lade zahl; falls nicht -> default"...

Gruß
 
Okay, vielen Dank Euch nochmal! ;)

Ich denke ich werde jetzt erstmal damit soweit zurecht kommen und ein wenig ausprobieren! Sollte was nicht klappen, melde ich mich noch mal!

Habe nur gedacht, dass es eventuell nicht so sinnvoll ist, immer und immer wieder onCreate aufzurufen. Das kostet ja auch immer wieder Ressourcen. Aber ich probiers erstmal so weiter!

Danke!

MfG
 
Hi nochmal,

habe mir jetzt ein wenig was durchgelesen... aber ich stocke gerade an dem Unterschied von onStart()/onStop() & onResume()/onPause().


onStart()/onStop() - "visible lifetime":
During this thime, the user can see the activity on-screen and interact with it.

onResume()/onPause() - "foreground lifetime":
Druing this time, the activity is in front of all ohter activites on screen and has user input focus.

Für mich klingt das jetzt in beiden Fällen ziemlich gleich wenn ich ehrlich bin. Wenn ich mit einer Activity interagieren kann, dann muss diese ja wohl auch im Vordergrund sein, über allen anderen Activities.
Anders herum: Wenn die Activity im Vordergrund ist sehe ich sie ja schließlich auch und kann mit ihr interagieren und "bedienen".

Also für mich folgt als Ergo daraus: Die eine Methode kann nicht ohne die andere Methode aufgerufen werden. Somit werden immer beide gleichzeitig ausgeführt. Ich würds ja gerne am "echten" Exemplar testen, aber mit den Methoden udn den zugehörigen Toasts komm ich nicht so weit :(
 
Nochmal:
Bei dir geht es gar nicht um "wiederherstellen" und wieder in den vordergrund. Das lass mal alles Android alleine machen!
Es geht darum, dass deine Zahl wahrscheinlich erstmal statisch ist. Also wird diese IMMER - oder ob onstart, oncreate onblubb - aufgerufen wird, angezeigt.

Gruß
 
Andrawit schrieb:
habe mir jetzt ein wenig was durchgelesen... aber ich stocke gerade an dem Unterschied von onStart()/onStop() & onResume()/onPause().

onStart()/onStop() - "visible lifetime":

onResume()/onPause() - "foreground lifetime":

Für mich klingt das jetzt in beiden Fällen ziemlich gleich wenn ich ehrlich bin. Wenn ich mit einer Activity interagieren kann, dann muss diese ja wohl auch im Vordergrund sein, über allen anderen Activities.

Es gibt auch den Fall, dass eine Activity visible ist, aber nicht im Vordergrund. Zum Beispiel wenn etwas teilweise transparentes darüber liegt.

Mein Kalender zeigt zum Beispiel Termin-Erinnerungen in einem Popup-Dialog an, wobei der Rest transparent ist und ich so die App im Hintergrund immer noch sehe. Wenn ich dann auf den transparenten Bereich klicke (also eigentlich auf die App dahinter) verschwindet das Popup und die eigentliche App wird wieder aktiv.
Bin aber nicht ganz sicher, ob das jetzt der Fall "user can interact with it" ist oder nur ein Feature meines Kalenders.

Bei diesem Fall würde beim erscheinen des Popups also bei der anderen Activity nur onPause aufgerufen und beim verschwinden des Popups dementsprechend wieder onResume
 
Genau, es geht z.B. um Dialoge die aufpoppen.
in OnPause kann man z.B. eine Animation stoppen und in onResume wieder starten, damit sie wenn die Acitivity im Hintergrund ist keine Resourcen verbraucht.
(Mir ist auf die schnelle kein besseres Beispiel eingefallen) :D
 
Hallo nochmal,

danke Euch für die Antworten! ;) Das ergibt alles Sinn...
Und das speichern der Daten klappt auch wunderbar mit den SharedPreferences. Bezüglich des immer wieder aufrufen von onCreate() und dem erstellen einer komplett neuen Activity habe ich den Zurück-Button einfach so "manipuliert" dass die Activity mit finish() geschlossen wird. Funktioniert super!

Ein Problem habe ich jedoch noch: Ich habe ein TextView in das über ein AlertDialog eine Nummer eingegeben wird und sich demnach stets ändert. Damit sich das ganze Layout nicht immer verschiebt hätte ich gern, dass das TextView rechtsbündig ist - bzw. sich der Text von "rechts auffüllt" und das TextView bei längerer Nummer nach links hin erweitert wird. Bis jetzt ist noch so, dass ich zwei TextViews in einem LinearLayout neben einander habe. Das linke ist linksbündig - so wie es soll. Nur das rechte klebt noch am linken TextView... aber es sollte rechtsbündig sein.

Versteht ihr was ich meine? Und könnt mir ggf. einen Tip geben?
 
RelativeLayout -> alignParentRight="true"

Gruß
 
Hallo nochmal...

es hängt schon wieder.
Habe ja bereits wie erwähnt eine 2. Activity "Einstellungen" die ich über das Menü aufrufe. Dann werden halt die Werte in den Einstellungen eingegeben und sollen dann in der MainActivity weiter verwendet werden. Habe mir dann Strings in der MainActivity erstellt die sich dann die Daten aus dem Intent ziehen. Problem ist nur, dass der Intent beim Starten der App noch garnicht besteht. Meine Frage ist jetzt: Wie kann ich das abfangen? Ich wollte das gern über eine If-Abfrage machen. Aber auf das Objekt, welches in der Einstllungs-Activity erstellt wird habe ich keinen direkten Zugriff.

MfG
 
1. Du hast das Prinzip der Shared Preferences verstanden
2. Du hast es nicht ;)


Bitte bei Punkt 1 anknüpfen, d.h. verstehe das Prinzip der SharedPreferences und wie man diese anwendet. Die Einstellungen die du per SharedPrefences tätigst musst du nicht per Intent weitergeben, sondern kannst sie später per SharedPreferences einfach auslesen. Ebenso gibt man beim Auslesen von SharedPreferences den Defaultwert an, der verwendet wird, falls die Einstellung noch nicht getätigt wurde.
 
Also ich hatte die SharedPreferences so verstanden, dass man damit manche Dinge innerhalb einer Activity speichern kann...

Also wenn ich dich verstanden habe dann speicher ich die Einstellungen in den SharedPreferences UND gebe diese damit noch an alle anderen Activitys aus. Quasi als Datenaustausch...

Auslesen der SharedPreferences in der Activity, wo ich diese ebenfalls gespeichert habe mache ich so:
Code:
tvPhoneNo.setText(getSharedPreferences(setTvPhoneNo, MODE_PRIVATE).getString(setTvPhoneNo, "Tel.-Nr. eingeben!"));

Das Auslesen und schreiben in den String in der MainActivity würde ich dann wie folgt machen:
Code:
phoneNo = getSharedPreferences(setTvPhoneNo, MODE_PRIVATE).getString(setTvPhoneNo, "Tel.-Nr. eingeben!");

Funktioniert aber nicht, weil er "setTvPhoneNo" (aus der Einstellungs-Activity) nicht kennt.

Ich raffs wirklich nicht... sorry für die Anstrengungen. Aber das ist halt der scheiß wenn man sich alles selbst beibringen muss und man es aus den ganzen englischen Guides nicht direkt kapiert :(
 
Bin hier grade nochmal drüber geflogen. Da steht nichts von "dinge innerhalb einer Activity speichern" :)
Ok, da steht auch nicht, dass sie global greifen. Allerdings steht da, dass man sie aufrufen kann, auch wenn die App gekillt worden ist...

Also:
Die Preferences kannst du dir überhall holen. Ob MainActivity, ob Service, ob BActivity oder BroadcastReceiver... Das ist schnurtzt.

Selbstversändlich kennt die MainActivity "setTvPhoneNo" nicht. Das ist wahrscheinlich eine statische final Variable (die man im übrigen koplett groß schreibt ^^)

Du hast nun mehreremöglichkeiten.
1. Schreib in der MainActivity dort einfach den selben namen rein wie bei der Settings-Activity
2. Mach dir eine extra klasse, in der du dir die namen immmer holst
3. übergebe den string von "setTvPhoneNo"...

Wobei eigentich nur 1 und 2 zu emfpeheln ist :D

Gruß

Ps.:
1. Du hast das Prinzip der Shared Preferences verstanden
2. Du hast es nicht ;)
 
Moin nochmal,

Anwendung funktioniert jetzt wie sie soll - auch die SharedPreferences. Jetzt kommt noch ein wenig Feinschliff:

Das rechtsbündige ausrichten des TextViews bzw. der Schrift des TextViews funktioniert einfach nicht. (RelativeLayout -> alignParentRight="true"). Um es noch einmal genau zu erklären: Im TextView steht standard-mäßig "Rufnummer eingeben". Dann klickt der Anwender auf den Button "Ändern" und ein AlertDialog mit Eingabe öffnet sich, wo dann die gewünschte Rufnummer eingegeben wird. Da Rufnummern eine unterschiedliche Länge haben, soll die letzte Ziffer IMMER am rechten Ende des TextViews steht, sodass ich immer einen festen Abstand von der letzten Ziffer zum Rand der Applikation habe... hoffe ich habe mich verständlich ausgedrückt.

Desweiteren noch folgendes: Die App hat 3 Buttons mit der auf Knopfdruck eine jeweilige festgelegte Nachricht an die eingestellte Rufnummer gesendet wird. Damit man nicht ausversehen 2 SMS direkt hintereinander verschickt oder das ganze als Spam missbraucht, möchte ich gerne eine gewisse zeitliche Sperre einbauen, sodass man erst wieder nach 1 oder 2 Minuten eine SMS versenden kann. Wie setze ich das am besten um? Habe mir gedacht einen String anzulegen der beim Drücken eines Buttons auf "blocked" gesetzt wird und mit Hilfe eines Timers wieder auf "permitted" rückgesetzt wird. Das ganze wird dann vor jedem Senden einmal abgefragt...
Gibts da eine bessere Lösung?

LG
 
statt einem String würde ich eine boolsche Variable nutzen (also true oder false).

Nur wenn die True ist darfst du senden, ansonsten mit nem timer zurück setzen.

Andere Möglichkeit wäre, die letzte Uhrzeit zu der du eine SMS verschickt hast auch in den sharedPreferences zu speichern und beim nächsten versenden zu prüfen ob genug Zeit vergangen ist, ansonsten könnte man die App beenden wieder öffnen und direkt die nächste SMS verschicken.
Wenn du die Zeit dauerhaft speicherst kannst du das besser kontrollieren.
 
Zurück
Oben Unten