Context

S

Snipestyle

Erfahrenes Mitglied
3
Hi zusammen,

ich brauche einmal kurz Hilfe bezüglich Context.

Ich habe eine Klasse die eine Activity extended.
Diese Activity ruft zu einem bestimmten Punkt eine andere Klasse auf und gibt Daten zurück. Wenn ich nun jedoch dann bspw einen AlertDialog nach der Ausführung anzeigen will bekomm ich folgenden logcat:

PHP:
10-09 20:36:59.019: D/AndroidRuntime(3147): Shutting down VM
10-09 20:36:59.019: W/dalvikvm(3147): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
10-09 20:36:59.119: E/AndroidRuntime(3147): FATAL EXCEPTION: main
10-09 20:36:59.119: E/AndroidRuntime(3147): java.lang.NullPointerException
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:132)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:65)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:142)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.app.AlertDialog$Builder.<init>(AlertDialog.java:359)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at de.schuldenmanagement.MainMenu.showData(MainMenu.java:145)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at de.schuldenmanagement.DataActivity.onPostExecute(DataActivity.java:130)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at de.schuldenmanagement.DataActivity.onPostExecute(DataActivity.java:1)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.os.AsyncTask.finish(AsyncTask.java:602)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.os.AsyncTask.access$600(AsyncTask.java:156)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.os.Looper.loop(Looper.java:137)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at android.app.ActivityThread.main(ActivityThread.java:4340)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at java.lang.reflect.Method.invokeNative(Native Method)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at java.lang.reflect.Method.invoke(Method.java:511)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-09 20:36:59.119: E/AndroidRuntime(3147):     at dalvik.system.NativeStart.main(Native Method)
Ich kann dem entnehmen das etwas mit dem Context nicht stimmt. Ich weiß nur nicht was. So ruf ich das ganze auf...

MainMenu
PHP:
new DataActivity(this,2).execute(String.valueOf(bridge.deine_id));
Nach der Verarbeitung in der DataActivity geht es dann so wieder zurück zu der MainMenu Klasse:
PHP:
 MainMenu m1 = new MainMenu();
                 m1.showData(result);
MainMenu
PHP:
    public void showData(String result) {
             AlertDialog.Builder builder1 = new AlertDialog.Builder(MainMenu.this);
          builder1.setTitle("Refreshing");
          builder1.setMessage(result);
          builder1.setCancelable(false);
          alert11 = builder1.create();
          alert11.show();
    }
Ich hoffe ihr könnt mir irgendwie helfen :thumbsup:
 
versuch mal den AlertDialog hier mit zu erstellen

Code:
new AlertDialog.Builder(super.getActivity())
 
Eclipse erlaubt mir dies leider nicht und will es zu getActionBar() oder zu getCallingActivity() ändern :/

Habe gerade mal weiter geschaut. Wenn ich nun in der showData Methode wiederum eine Methode einer anderer Klasse aufrufe gibt es auch direkt nullpointer exceptions. Also irgendwas muss mit dem Context falsch laufen
 
Zuletzt bearbeitet:
und wenn du statt
Code:
MainMenu.this
nur
Code:
this
nimmst?
 
Das hatte ich vorher und hat leider genauso wenig bewirkt :/

Also irgendwas stimmt da nicht. Nachdem die DataActivity ausgeführt wurde findet er halt auch eine Views mehr von mir etc. Wie ob der Fokus auf einer anderen Activity liegen würde
 
verwendest du womöglich in einer der XML Dateien den TAG "tools:context" und der weist auf den falschen Context hin?

Wann ist das Problem denn zum ersten mal aufgetaucht? Andere Activitys klappen?
 
Diese Activity ruft zu einem bestimmten Punkt eine andere Klasse

Ruft deine Activity eine andere Activity oder nur eine Klasse auf (die zB Datenzeugs runterlädt) ???

Wenn du eine andere Activity aufrufst, kannst du nie davon ausgehen, das die "aufrufende" noch im Speicher ist. Android erschafft die nach Bedarf (Speicherknappheit) und Belieben neu. Daher bringt die Übergabe von Contexts bzw. Pointern auf Textviews gar nichts. -> so etwas führt unweigerlich zu Nullpointern.

Ich bring diesen Hinweis nur, weil du gerade schriebst das er auch keine anderen Views mehr findet. Das ist meist ein eindeutiges Indiz.
 
Die Klasse(MainMenu) ist eine Activity und ruft eine non Activity Klasse (DataActivity) auf. In der DataActivity wird dann die Klasse mit der Activity aufgerufen (MainMenu). Sobald dies geschehen ist, verfüge ich dann aber über keinerlei Zugriffe mehr auf die ganzen Views und kriege die Nullpointer.
Wie soll ich denn nun vorgehen, das ich keine Nullpointer mehr bekomme?
 
Hmm eine Activity MainMenu zu nennen ist etwas verwirrend,
aber egal.

Fangen wir am besten vorne an und du erklärst einfach mal was du vor hast.
Ich glaub du hast da ein konzeptionelles Problem.

-> Hinweis: Daten zwischen 2 Activities tauscht man über Intents (Bundles,, .putExtra ectpp) aus oder du speichesrt die Daten woanders zwischen

SharedPrefs, Datenbank, globaler Singelton
 
Ist "eigentlich" relativ simpel erklärt.
Die MainMenu Activity ruft die DataActivity auf. Die DataActivity führt darauf hin ein paar Zugriffe auf php Dateien aus und liest etwas aus. Das Ergebnis gibt bzw. soll mir dann die DataActivity zurück in die MainMenu Activity geben, wo ich dieses dann weiterverarbeiten bzw. Ausgeben kann.

Reicht das an Informationen oder musst du mehr wissen?:confused2:
 
Ok,

was halt für mich verwirrend ist, du nennst es DatenActivity und schreibst non Activity Klasse.
Wenn es nur darum geht Daten herunter zu laden, dann kannst du es ja auch in deiner MainActivity machen bzw. in eine "normale" Javaklasse mit Funktionen packen und diese ganz klassisch aus der Mainactivity aufrufen.
Also Funktionsaufruf und Daten als Rückgabeparameter, dann verlässt du niemals den Context.

Deswegen die Frage nach dem Konzept.

Um bei deinem Ansatz zu bleiben musst du dich lediglich um die
Datenübergabe kümmern. Sprich wenn deine Datenactivity aufgerufen wird (per Intent) übergibst du die Parameter was geladen werden soll
und rückwärts genau so. Sprich wenn du in der DatenActivity fertig bist und die MainMenuActivity wieder aufrufst gibst du hier die Ergebnisse aus der Datenactivity mit.

http://developer.android.com/reference/android/os/Bundle.html

http://congeritc.blogspot.de/2012/04/android-passing-values-between-views.html
 
Aktuell rufe ich die DatenActivity so auf:

PHP:
new DataActivity(this,2).execute(String.valueOf(bridge.deine_id));

mit nem Intent würde ich das dann so machen
PHP:
Intent myIntent = new Intent(context, MainMenu.class);
myIntent.putExtra("id", String.valueOf(bridge.deine_id));
context.startActivity(myIntent);

und in der DataActivity dann so empfangen:
PHP:
Intent intename = getIntent();
String uname = (String) intename.getStringExtra("id");

und in der DataActivity dann genau das selbe zurück zur MainActivity, richtig ?
 
genau, nur das du um die Datenactivity aufzurufen, auch die hinschreiben müsstest

Intent myIntent = new Intent(this, Datenactivity.class);
myIntent.putExtra("id", String.valueOf(bridge.deine_id));
startActivity(myIntent);
und retour halt, die MainMenu.class



PS:
Wie gesagt ich hoffe wir schrammen hier nicht an der Begrifflichkeit aneinander vorüber. Mit den Intents gehen wir jetzt wirklich davon aus, das DatenActivity auch eine Activity ist.
Dein "
new DataActivity(this,2).execute(String.valueOf(bridge.deine_id));" sah / sieht halt mehr wie Klassenaufruf eines AsyncTasks aus. Naja wir kommen schon auf einen Nenner


 
Zuletzt bearbeitet:
Okay gut.
Ein Problem gibt es jedoch. Meine DatenActivity meckert über folgende Zeile:
PHP:
Intent intename = getIntent();
Eclipse bietet mir dann an diese Methode zu erstellen. Warum ?:confused2:


EDIT: Okay dann haben wir ein Problem. denn die DatenActivity extended einen Asynctask. Ich hab der Klasse echt einen unpassenden Namen gegeben sorry
 
Der folgende Code ist dein Hauptproblem:

Code:
MainMenu m1 = new MainMenu();
m1.showData(result);

Es macht keinen Sinn, eine neue Instanz der Activity zu erstellen. Erstens gibts die Activity noch, da du ja nur einen AsyncTask startest. Zweitens hat die Activity so keinen gültigen Kontext.

Du hast deinen Code aber schon fast korrekt vorbereitet, nur der obengenannte Aufruf von ist falsch.

In der Zeile

Code:
new DataActivity(this,2).execute(String.valueOf(bridge.deine_id));

übergibst du deinem AsyncTask bereits eine Referenz der Activity (mit this), und damit auch den benötigten Kontext. Deshalb kannst du dann einfach auf dieser Referenz die Methode showData(). Natürlich ebenfalls in onPostExecute() des AsyncTasks.

Als vereinfachtes Beispiel könnte dein Code etwa so aussehen:

Code:
public class DataActivity extends AsyncTask<...> {
  private Activity myActivity;

  public DataActivity(Activity a, int i) {
    myActivity = a;
    
    //was sonst noch so da steht
  }

  @Override
  protected void onPostExecute(...) {

    //hier der Aufruf
    myActivity.showMenu(...);
  }
}
 
Okay dann vergessen wir mal das Ganze mit der zweiten Activity.

Wenn du aus deiner Activity MainMenu (die ja hoffentlich eine richtige Activity) ist, irgend etwas startest, was ein Funktionsaufruf ist, dann verlässt du auch nicht den Context und du musst sie nach dem AsyncTask auch nicht neu starten.

Wahrscheinlich steckt hier eher dein Verständnisproblem.

Ein AsyncTask läuft parallel zur eigentlichen App.
Um zu erkennen wann er fertig geworden ist, nutzt du die Methoden

Code:
     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }

Wichtig hier zu wissen ist: dein Thread/AsyncTask kann nicht auf Elemente des Gui zugreifen!!! Dies ist erst wieder in der onPostExecute Methode möglich. Falls du das versuchts -> Crash/Nullp
So ein "normaler" Ablauf,

Activity -> User drückt Button oder anderes Event (onStart) stößt den
Update/Ladevorgang an.

-> AsyncTask wird angestossen
-> hier kannst du in onPreExecute
dem User einen Progressdialog angezeigen und somit zeigen,das
etwas lädt (wenn gewünscht)

-> Verarbeitung läuft
-> sobald onPostExecute erreicht wird, kannst du auch wieder
auf das GUI zugreifen

-> ProgressDialog dismissen
-> result/daten in deine Textviews füllen
-> Fertig

Die Sache mit dem Progressdialog ist ja kein Muss, du musst nur Bedenken
sobald der AsyncTask läuft und du den User nocht blockierst, kehrt deine App wieder zur normalen Funktion zurück,
das heisst der User kann weitere Eingaben tätigen die App verlassen
ect pp.

Sprich, wenn du zwingend die Daten für die weiteren schritte in der
App brauchst -< solltest du auf den erfolgreichen Dload warten
.
 
Ahh okay !

Habe das mal so editiert.

Jetzt bekomme ich bei der Zeile


//hier der Aufruf myActivity.showMenu(...);ein Problem.

Eclipse sagt mir ich müsste einen Cast hinzufügen, da die Methode die ich aufrufen will für "myActivity" nicht exisitert.
Natürlich versuche ich eine Methode aufzurufen, die auch wirklich exisitert

Der ursprüngliche Beitrag von 20:47 Uhr wurde um 21:06 Uhr ergänzt:

So, schonmal den ersten Erfolg !
Das mit den Alert Dialog klappt nun, ich bekomme ihn ohne Nullpointer Exception !

Danke euch beiden schonmal dafür!

Jedoch kommt nun mein zweites Problem immer noch zum tragen.
Ich rufe in der MainMenu Klasse wiederum eine Methode einer Fragment Klasse auf, da ich dort nun etwas mit den gewonnenen Daten ändern muss. Jedoch passieren genau da weitere Nullpointer exception. Also in der Methode wird eigentlich nur eine ListView per findViewById gesucht. Wird die Methode dann ausgeführt gibts den Logcat:

PHP:
10-11 18:57:11.129: D/AndroidRuntime(2240): Shutting down VM
10-11 18:57:11.129: W/dalvikvm(2240): threadid=1: thread exiting with uncaught exception (group=0xb4d50908)
10-11 18:57:11.129: E/AndroidRuntime(2240): FATAL EXCEPTION: main
10-11 18:57:11.129: E/AndroidRuntime(2240): java.lang.NullPointerException
10-11 18:57:11.129: E/AndroidRuntime(2240):     at de.schuldenmanagement.SchuldenFragment.loadUebersicht(SchuldenFragment.java:70)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at de.schuldenmanagement.MainMenu.analyzeData(MainMenu.java:162)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at de.schuldenmanagement.DataActivity.onPostExecute(DataActivity.java:132)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at de.schuldenmanagement.DataActivity.onPostExecute(DataActivity.java:1)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at android.os.AsyncTask.finish(AsyncTask.java:631)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at android.os.Looper.loop(Looper.java:137)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at android.app.ActivityThread.main(ActivityThread.java:5039)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at java.lang.reflect.Method.invokeNative(Native Method)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at java.lang.reflect.Method.invoke(Method.java:511)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-11 18:57:11.129: E/AndroidRuntime(2240):     at dalvik.system.NativeStart.main(Native Method)
 
Ich rufe in der MainMenu Klasse wiederum eine Methode einer Fragment Klasse auf, da ich dort nun etwas mit den gewonnenen Daten ändern muss. Jedoch passieren genau da weitere Nullpointer exception. Also in der Methode wird eigentlich nur eine ListView per findViewById gesucht. Wird die Methode dann ausgeführt gibts den Logcat:

Nullpointer heisst ja oft, das du auf etwas nicht initalisiertes zugreifst,
daher die Frage - wie greifst du auf das Fragment zu ?, ist das Fragment statisch per xml oder dynamisch per code eingebunden.

Nicht vergessen, Fragment hat dann ein eigenes Layout, welches vom Fragment in onCreateView erschaffen wird.

zBsp:

View rootView = inflater.inflate(R.layout.fragment_startseite, container,
false);

um dann einen View zu finden musst du natürlich auch dort suchen.

tv1 = (TextView) rootView.findViewById(R.id.textView1);


Und was immer bei der Fehlersuche hilft... gegen NULL testen


if (listview1 != null){
...mit Daten befüllen
} else {
Log.d("TEST", "Fehler kein Zugriff auf Listview");
}
 
Beim Aufruf der MainMenu Activity lade ich auch schon gleichzeitig inhalte in die listview des fragments, also intialisert ist alles und funktioniert eigentlich auch, daher ist das etwas seltsam.

Nach rückgabe der daten von der datenactivity in die mainmenu klasse passiert folgendes:

Zunächst wird einmal

PHP:
UebersichtFragment uebersicht;

erstellt


Kommen die Daten dann zurück wird in der Methode initialisiert:
PHP:
uebersicht = new UebersichtFragment();

Nun wird die Methode der UebersichtFragment Klasse aufgerufen
PHP:
uebersicht.loadUebersicht(data);

in der Klasse UebersichtFragment sieht die Methode wie folgt aus:
PHP:
public void loadUebersicht(Vector<String> data) {
        msgList = (ListView)rootView.findViewById(R.id.UebersichtList);
    }

Das allein reicht schon für die Nullpointer Exception. Natürlich wurde msgList vorher in der Klasse erstellt.
PHP:
public class UebersichtFragment extends Fragment{
     ListView msgList;
....
 
pack doch das

msgList = (ListView)rootView.findViewById(R.id.UebersichtList);

gleich in das onCreateView, des
UebersichtFragment Fragmentes.
findViewById durchsucht sonst bei jedem Aufruf den Layouttree und das kostet Zeit
 

Ähnliche Themen

kukuk
Antworten
0
Aufrufe
719
kukuk
kukuk
T
Antworten
1
Aufrufe
835
T3tris
T
Zurück
Oben Unten