1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Datenbankverbindung in andere Klasse verschieben...

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von assenda, 23.12.2010.

  1. assenda, 23.12.2010 #1
    assenda

    assenda Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    55
    Erhaltene Danke:
    0
    Registriert seit:
    02.12.2010
    Hey alle zusammen!

    bin grade dabei, meinen Code etwas zu überarbeiten und in Funktionen bzw neue Klassen zu verlagern.

    Dabei bin ich bei einer FUNKTIONIERENDEN Datenbankverbindung auf ein Problem gestoßen:

    Die vorhandenen Daten werden nicht mehr angezeigt, sobald ich die
    verbindung in
    Verbindung.java verschiebe.


    class A:

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    new Verbindung(getApplicationContext());
    ...
    --------------

    Da in der Verbindung.java für die neue Datenbank vorher getApplicationContext() benutzt wurde, und beim bloßen verschieben ein Fehler aufgetreten ist, hab ich den Context aus class A übergeben
    (richtig?!) -- Zumindest treten so keine Fehler auf...

    Verbindung:

    public verbindung(Context context) {
    myDatabase db = new myDatabase(context, DB_NAME, null, DB_VERSION);

    try {

    sql = "Select...";
    .
    .
    .
    int[] to = new int[] { R.id.item1, R.id.item2, R.id.item3, R.id.item4, R.id.item5 };
    .
    .
    .
    } catch (Exception e) {
    //TextView tv = (TextView) findViewById(R.id.error);
    //tv.setText("ERROR: " + e.getMessage().toString() + " \n SQL: " + sql);
    }
    -----------

    NUR wenn ich alles in die Verbindung.java verschiebe, wird nichts ausgegeben!

    Nach vielem Testen hab ich festgestellt, dass das Programm komplett abschmiert, wenn ich im catch NICHT auskommentiere. (Auch nur nach Verschieben)

    Deshalb gehe ich davon aus, dass das Programm aus Verbindung.java nicht auf R.id.error und die anderen ids zugreifen kann...

    (Allerdings muss ich die R.id.item1 ... nicht auskommentieren, damit das Programm nicht abschmiert, was mich sehr wundert.
    Wird einfach nur nichts mehr angezeigt...

    Was denkt ihr?!

    Danke!
     
  2. the_alien, 23.12.2010 #2
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Wenn es abschmiert... poste doch mal den Stacktrace...
     
  3. assenda, 23.12.2010 #3
    assenda

    assenda Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    55
    Erhaltene Danke:
    0
    Registriert seit:
    02.12.2010
    Hey...danke für die schnelle Antwort...Leider schaffe ich es nicht, so ein stacktrace einzubauen..
    hab da verschiedene Varianten gesehen, vom log, bis zum remotestacktrace...

    also ich finde alle möglichen klassen, die vom exeption Handler erben..

    Der z.B: Get Stacktrace as String - Android Forum - AndroidPIT

    weiß aber nicht wie ich die benutzen kann..
    Hast du n Tipp, wo es leicht erklährt ist? Möglichst auf Deutsch, da mir die englischen anleitungen echt schwer fallen zu lesen...

    Danke!
     
  4. ts-apps, 24.12.2010 #4
    ts-apps

    ts-apps Erfahrener Benutzer

    Beiträge:
    194
    Erhaltene Danke:
    39
    Registriert seit:
    27.03.2010
    Ääähm der Stacktrace wird dir in deiner Eclipse Log Cat View angezeigt.
     
  5. PeaceI, 24.12.2010 #5
    PeaceI

    PeaceI Android-Hilfe.de Mitglied

    Beiträge:
    65
    Erhaltene Danke:
    12
    Registriert seit:
    26.07.2009
    Ich tippe ich mal darauf, dass er deine Ressourcen (den ganzen Kram mit R.bla.id) nicht findet. Diese sind jedoch über den Context der Activity, den du ja mit in die Verbindungs-Klasse gibts, erreichbar. Lösung wäre also sowas:

    Ressources ress = context.getRessources();

    ...

    int[] to = new int[] { ress.getInt(R.id.item1), ress.getInt(R.id.item2), ress.getInt(R.id.item2), ress.getInt(R.id.item5), ress.getInt(R.id.item5) }

    ...

    ...allerdings ohne Gewähr, ist nur so adhoc hingetippt ;)

    Edit:
    Ok, es wird so nicht laufen, du legst ja in dem int-Array wirklich die Ids selber und keine ints, wie ich erst dachte, ab. Diese werden dann wohl später irgendwo ausgelesen und anhand derer irgendwelche Views aus den Ressourcen geholt. Hierbei müssen die Views dann wirklich aus deinen Ressourcen, die über deinen Context erreichbar sind geholt werden.
     
    Zuletzt bearbeitet: 24.12.2010
  6. assenda, 03.01.2011 #6
    assenda

    assenda Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    55
    Erhaltene Danke:
    0
    Registriert seit:
    02.12.2010
    Hey sry, war eine längere Zeit nicht home...
    Hab jetzt die Errors ausgegeben..(danke an ts-apps!)

    Werde mir jetzt noch den Vorschlag von PeaceI angucken, wenn jemand sieht, dass es an etwas anderem liegt, sagt doch bitte bescheid!

    Vielen Dank!

    assenda


    Log:

    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): FATAL EXCEPTION: main
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.apk.database/de.apk.database.databaseActivityTest}: java.lang.NullPointerException
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2787)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.app.ActivityThread.access$2300(ActivityThread.java:135)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.os.Handler.dispatchMessage(Handler.java:99)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.os.Looper.loop(Looper.java:144)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.app.ActivityThread.main(ActivityThread.java:4937)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at java.lang.reflect.Method.invokeNative(Native Method)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at java.lang.reflect.Method.invoke(Method.java:521)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at dalvik.system.NativeStart.main(Native Method)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): Caused by: java.lang.NullPointerException
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:100)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at de.apk.database.verbindung.<init>(verbindung.java:24)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at de.apk.database.databaseActivityTest.onCreate(databaseActivityTest.java:30)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
    01-03 11:58:49.857: ERROR/AndroidRuntime(2057): ... 11 more
     
  7. Kranki, 03.01.2011 #7
    Kranki

    Kranki Ehrenmitglied

    Beiträge:
    3,831
    Erhaltene Danke:
    814
    Registriert seit:
    19.07.2009
    Tablet:
    Samsung Galaxy Tab 3 7.0 Lite
    Was steht denn in databaseActivityTest.java in Zeile 30?
     
  8. assenda, 03.01.2011 #8
    assenda

    assenda Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    55
    Erhaltene Danke:
    0
    Registriert seit:
    02.12.2010
    hm wird wohl nicht weiterhelfen...ist nur der Tryblock:

    (30) try {
    ...
    } catch (Exception e) {

    TextView tv = (TextView) findViewById(R.id.error);
    tv.setText("ERROR: " + e.getMessage().toString() + " \n SQL: " + sql);

    }


    Hab jetzt übrigens versucht, auf die ressourcen zuzugreifen, aber ohne erfolg...(so wie peaceI es gedacht hat..)

    Also evtl. kann es daran liegen, dass ich in der verbindung.java ebenfalls "extends Activity" hab...?!
    wenn ich das wegnehme, kann ich bei einzelnen elementen
    durch context."" darauf zugreifen. z.B:

    myDatabase db = new myDatabase(context.getApplicationContext(), DB_NAME, null, DB_VERSION);

    dann gibt er da keinen Fehler aus..
    Allerdings werden folgende Elemente als fehler markiert: (auch wenn ich context."" vorschreibe:

    startManagingCursor(result);
    ListView lv = (ListView) findViewById(R.id.listview); ( the method findV...ist undefiniert für Verbindung - ist ja klar, weil kein extends Activity)

    sobald ich diese sachen ausklammere, wird die apk ausgeführt!!
    dann wird aber nichts (aus der Datenbank) mehr angezeigt (klar, weil dann nicht mehr auf xml zugegriffen wird)
    Der rest wird ausgegeben...

    ----

    Anscheinend muss ich auf die Activity zugreifen, (ist die nicht im context?!) hätte gedacht: context.findViewById....
    aber das geht nicht...
    Hat da jemand einen vorschlag?! Die methode findViewById ist ja aus Activity...
     
    Zuletzt bearbeitet: 03.01.2011
  9. assenda, 03.01.2011 #9
    assenda

    assenda Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    55
    Erhaltene Danke:
    0
    Registriert seit:
    02.12.2010
    Ich habe mir gedacht, dass es vllt Sinnvoller ist, wenn ich das Projekt einmal hochlade damit das jemand mal testen kann, wenn die Zeit/Lust da ist...

    Vllt drücke ich mich einfach nicht verständlich genug aus, was das problem ist...

    Wäre jemand so nett und kann sich das angucken?!
    (ist wirklich nicht viel code..hauptsächlich nur die datenbank verbindung...)

    dbVerbindung funktioniert, new Verbindung nicht!

    ich will das new Verbindung funktioniert (selber content!)
    -----------
    //new verbindung(getApplicationContext());
    dbVerbindung();
    -----------
    hier der Pfad zum Projekt:
    assenda.de/database.zip
     
  10. fexpop, 03.01.2011 #10
    fexpop

    fexpop Android-Experte

    Beiträge:
    877
    Erhaltene Danke:
    128
    Registriert seit:
    17.07.2009
    Mir ist nicht ganz klar, was Du eigentlich erreichen möchtest. Was soll die Klasse "verbindung" wirklich erledigen?

    Momentan hast Du aus "verbindung" eine weitere Activity gemacht, die aber weder in Manifest.xml deklariert wird, noch in irgendeiner Weise - also z.B: startActivity() oder startActivityForResult() - gestartet wird. Dargestellt wird so immer die View aus databaseActivityTest, die aber keine Daten erhält, weil dbVerbindung() auskommentiert ist.

    --Felix
     
  11. PeaceI, 03.01.2011 #11
    PeaceI

    PeaceI Android-Hilfe.de Mitglied

    Beiträge:
    65
    Erhaltene Danke:
    12
    Registriert seit:
    26.07.2009
    Ok, ich habe mal in die API und dein Prog geschaut. Man kommt von den Resources oder vom Context tatsächlich nicht an die Views heran (wie ich zuvor dachte, mein Fehler, sorry). Das macht allerdings auch Sinn. Da z.B. eine Klasse zur Verbindung an eine Datenquelle nicht selbst auf der Gui zu arbeiten hat.
    Die Verbindung von Activity erben zu lassen wird dein Problem auch nicht lösen und macht auch keinen Sinn. Eine Activity ist grob gesagt immer eine "Ansicht" auf dem Bildschirm und sollte am besten nie direkt von Hand instanziiert werden, sondern wenn, dann über Intents, aber das ist eine andere Sache.
    Um das ganze nun nicht kompliziert zu machen, könntest du das entsprechende View oder gar die ganze Activity an die Verbindung reichen und die fraglichen Methoden an der Activity aufrufen. Das wäre zwar ziemlich unschön, aber wird hinhauen. Allerdings kann man sich dann auch fragen, warum man die Verbindung überhaupt auslagert.
    Normalerweise sollte die Activity sich die nötigen Daten aus dem Verbindungobjekt herausholen (z.B. über get-Methoden) und selbst die Views bearbeiten.
     
  12. assenda, 03.01.2011 #12
    assenda

    assenda Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    55
    Erhaltene Danke:
    0
    Registriert seit:
    02.12.2010
    Also erstmal danke für die ganzen Antworten...

    Wie schon gesagt, die Klassen Verbindung sollte einfach die selben aufgaben erledigen wie die Methode dbVerbindung() - die ja funktioniert.....

    Wollte das ganze einfach nur auslagern.

    Hab gedacht, dass es eher der übersicht dienen würde...
    Aber peaceI meint ja, das das nicht wirklich sinn macht, deshalb werde ich dann wohl die Methoden in der Klasse lassen müssen...

    (Das mit den GET/SET Methoden war mir im Prinzip klar, ich wollte nur erstmal das Auslagern versuchen, bevor ich die Aufgaben auf die einzelnen Methoden verteile..)

    Vielen Dank für die Infos...
     
  13. the_alien, 04.01.2011 #13
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Puh, da ist aber so einiges im argen mit dem Design...

    1. Klassennamen werden der Konvention nach groß geschrieben. Es ist kein muss, aber ein SOLL. (NO TITLE)

    2. Du baust in der Klasse "verbindung" im Konstruktor direkt die Verbindung auf, holst die Daten und willst sie weiterverarbeiten. Das gehört in eine Methode. Im Konstruktor sollen nur die Voraussetzungen geschaffen werden um die Abfrage machen zu können. Besser wäre es hier, wenn du im Konstruktor nur den Context in eine Instanzvariable speicherst und den ganzen Rest in eine Methode auslagerst.

    3. Das SQL Import Statement in der Klasse "verbindung" sollte in die onCreate() Methode von "myDatabase".

    4. Activities sind quasi Fenster einer Applikation. Eine Verbindung an eine Datenbank ist kein Fenster. Das Ergebnis der Datenbankabfrage soll nur in einem Fenster angezeigt werden. Schlussfolgerung: "verbindung" DARF KEINE Activity sein.

    5. Natürlich kannst du keine neue Instanz von "verbindung" erstellen, denn die Activity erstellst DU und nicht das FRAMEWORK. Darum geht der Aufruf von getApplicationContext() in Zeile 27 von "verbindung" schief. Wäre "verbindung" KEINE Activity, dann wärst du vielleicht selber auf die Idee gekommen den Context zu nehmen, den du selber übergibst und nicht getApplicationContext() zu nutzen.

    6. findViewById() funktioniert nicht. Die Activity wird nicht angezeigt, hat keinen contentView gesetzt und dementsprechend kann findViewById() niemals etwas zurück liefern. Hier sind wir wieder bei der Methode... erstelle eine Methode die z.B. den Cursor zurückgibt den du dir von der Datenbank holst. Dann kannst du diese in deiner "databaseActivityTest" Klasse aufrufen und das Ergebnis anzeigen.

    7. Für eine SELECT Abfrage braucht man keine schreibbare Datenbank. Warum öffnest du sie dann schreibbar?

    8. Weniger Copy&Paste Programmierung bitte...
     
    assenda bedankt sich.

Diese Seite empfehlen