Java [Android] Problem mit BackgroundService

FaKer

Cadet 4th Year
Registriert
Jan. 2004
Beiträge
100
Hallo mal wieder :)

ich bekomme von einem REST-Service eine ganze Reihe an Daten die in einer DB gespeichert werden. Genau genommen werden 3 Tabellen aus meiner Datenbank mit Daten gefüllt.

Bei Tabelle 1 und 2 funktoiniert soweit alles.

Nun gehts aber mit Tabelle 3 weiter. Der Unterschied zu den Daten die in Tabelle 1 und 2 eingetragen werden ist, dass es sich nun nichtmehr blos um max. 50 Datensätze handelt, sonder um mehrere 1000.

Ich habe ab einer bestimmten größe an Daten, die ich von dem REST-Service bekomme, festgestellt, dass iwann eine Memory Exception fliegt. Das passiert in der Zeile, wo mein "Result-String" aus dem InputStream zusammengebaut wird.

Ich wollte das Problem umgehen, indem ich die REST-Requests mit Query-Parametern versehe, so dass pro Request eine kleinere Datenmenge zurückgeliefert wird.

Ich hab mir das so vorgestellt, dass ich einfach mehrmals die Service-Funktion, die die Daten vom REST-Service holt, aufrufe, aber immer mit unterschiedlichen Parametern. Doch das scheint nicht so recht zu funktionieren. Evtl. habe ich das Prinzip von Services nicht richtig verstanden?

Hier mal der Code aus der Activity wo der Service aufgerufen wird:



Code:
  private NetzwerkService.NetzwerkServiceBinder mNetzwerkBinder;
  ...
  private ServiceConnection mNetzwerkServiceConnection = new ServiceConnection() {
    
    @Override
    public void onServiceDisconnected(ComponentName name) {
      // TODO Auto-generated method stub
      
    }
    
    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
      mNetzwerkBinder = (NetzwerkService.NetzwerkServiceBinder) binder;
      mNetzwerkBinder.getSps();
      mNetzwerkBinder.getDetails();
      
      // Wenn Werte vorhanden, solange neue Werte im "Tagestakt" anfordern, bis sie aktuell sind.
      if(werteVorhanden) {
        do {
          mNetzwerkBinder.getPowerdetails(vonTs, bisTs);
          
          vonTs = bisTs;
          bisTs += tagInSekunden;    
        } while (bisTs <= simCurrentTime + tagInSekunden);
      } else {
        for(int i = 0; i < 6; i++) {
          mNetzwerkBinder.getPowerdetails(vonTs, bisTs);
          
          bisTs = vonTs;
          vonTs -= tagInSekunden;
        }
      }
    }
  };

Die BinderKlasse meines NetzwerkSerivce:

Code:
public class NetzwerkServiceBinder extends Binder implements INetzwerkService {

    @Override
    public void getSps() {
      
      new Thread() {
        @Override
        public void run() {
          while(mIsBusy) {
            try {
              sleep(1000);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
          Log.d(TAG, "getSps()");
          mIsBusy = true;
          _getSps(getSpsURL);
          mIsBusy = false;
        }
      }.start();
    }

    @Override
    public void getDetails() {
      
      new Thread() {
        @Override
        public void run() {
          while(mIsBusy) {
            try {
              sleep(1000);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
          Log.d(TAG, "getDetails()");
          mIsBusy = true;
          _getDetails(getDetailsURL);
          mIsBusy = false;
        }
      }.start();
    }
    
    @Override
    public void getPowerdetails(final int vonTs, final int bisTs) {
 
      new Thread() {
        @Override
        public void run() {
          while(mIsBusy) {
            try {
              sleep(1000);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
          Log.d(TAG, "getPowerdetails()");
          mIsBusy = true;
          _getPowerdetails(getPowerdetailsURL + "?where=vonTs="+vonTs+"&bisTs="+bisTs);
          mIsBusy = false;
        }
      }.start();
    } 
  }

Hier noch der Fehler:

Code:
WARN/System.err(732): java.lang.IllegalArgumentException: size must be > 0
WARN/System.err(732):     at java.io.BufferedReader.<init>(BufferedReader.java:119)
WARN/System.err(732):     at de.test.services.NetzwerkService.convertInputStreamToString(NetzwerkService.java:263)
WARN/System.err(732):     at de.test.services.NetzwerkService.getJSONObject(NetzwerkService.java:234)
WARN/System.err(732):     at de.test.services.NetzwerkService._getSps(NetzwerkService.java:137)
WARN/System.err(732):     at de.test.services.NetzwerkService.access$4(NetzwerkService.java:136)
WARN/System.err(732):     at de.test.services.NetzwerkService$NetzwerkServiceBinder$2.run(NetzwerkService.java:82)
WARN/System.err(732): java.lang.NullPointerException
WARN/System.err(732):     at de.test.services.NetzwerkService._getSps(NetzwerkService.java:141)
WARN/System.err(732):     at de.test.services.NetzwerkService.access$4(NetzwerkService.java:136)
WARN/System.err(732):     at de.test.services.NetzwerkService$NetzwerkServiceBinder$2.run(NetzwerkService.java:82)
WARN/System.err(732): java.lang.IllegalArgumentException: size must be > 0
WARN/System.err(732):     at java.io.BufferedReader.<init>(BufferedReader.java:119)
WARN/System.err(732):     at de.test.services.NetzwerkService.convertInputStreamToString(NetzwerkService.java:263)
WARN/System.err(732):     at de.test.services.NetzwerkService.getJSONObject(NetzwerkService.java:234)
WARN/System.err(732):     at de.test.services.NetzwerkService._getDetails(NetzwerkService.java:160)
WARN/System.err(732):     at de.test.services.NetzwerkService.access$5(NetzwerkService.java:159)
WARN/System.err(732):     at de.test.services.NetzwerkService$NetzwerkServiceBinder$3.run(NetzwerkService.java:103)
WARN/System.err(732): java.lang.NullPointerException
WARN/System.err(732):     at de.test.services.NetzwerkService._getDetails(NetzwerkService.java:164)
WARN/System.err(732):     at de.test.services.NetzwerkService.access$5(NetzwerkService.java:159)
WARN/System.err(732):     at de.test.services.NetzwerkService$NetzwerkServiceBinder$3.run(NetzwerkService.java:103)

Ich finds äußersts merkwürdig, dass im Log die Funktion _getSps() angezeigt wird. Diese funktionert eignetlich ohne Probleme. Ich denk dass das ganze evtl. an nem falschen Verständnis für Services meinerseits zusammenhängt?!

Ist es evtl. nicht möglich, die ServiceFunktion getPowerdetails(String,String) mehrmals mit versch. Paramtern aufzurufen?!

Danke für eure Hilfe!


Das ganze lehnt sich an das Beispiel aus "Android 2 - Grundlagen und Programmierung" von Becker, Pant.
 
Hm schau doch mal mit dem Debugger nach, warum da diese Exceptions geworfen werden.
 
Bin ein wenig weiter:

Ich hatte die buffer size vom BufferReader mit einem Wert initialisiert:

Code:
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
long bufferSize = entity.getContentLength();
...
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream), (int)bufferSize);

In miener Log-Ausgabe hab ich grad gesehen, dass bufferSize = -1.
Deswegen wohl die Fehlermeldungen.

Ich habe daraufhin den BufferedReader-Konstruktor ohne vorgegeben Größe genommen. Damit tauchen die Fehlermeldungen nicht mehr auf.

Und die Daten kommen wieder an und werden auch in die DB geschrieben.

Jetzt hab ich aber noch das Problem, dass ja normalerweise, die getPowerdetails() mehrere Mal mit versch. Parametern aufgerufen werden soll. Das passiert aber nicht. Laut meinen Log-Ausgaben wir diese ein Mal aufgerufen, genauso wie getSps() und getDeatails().

// Evtl muss ich nochmal meine Bedingung aus der while-Schleife prüfen... *grübel* brb ;)

War n kleiner Logikfehler drin... nun wird zwar getPowerdetails() zwei Mal aufgerufen, aber es werden blos Werte vom ersten Mal in meine DB eingetragen ohne das ieine Fehlermeldung fliegt... weiter probieren ;)

Merci aber wieder Mal für deine Hilfe


// Eine Verständnisfrage:

Ich rufe ja in der while- bzw. for-Schleife jeweils eine Methode auf, in der ein new Thread() steht. Das bedeutet also, dass mit jedem Schleifendurchlauf ein neuer Thread gestartet wird und dieser dann seine Aufgabe erledigt? Wie verhält sich das dann mit dem Datenbankzugriff? Passieren diese nacheinander? weil falls die gleichzeitig passieren würden, gäbe es ja einen Lock...
 
Zuletzt bearbeitet:
Also die Threads werden gleichzeitig gestartet, aber sie schreiben ja nicht gleichzeitig auf die DB, sondern erst wenn die Antwort kommt, also dürfte das nacheinander stattfinden.
Kannst dir aber ja mal vor und nach dem Datenbankzugriff eine Log-Meldung ausgeben lassen, um auszuschließen, dass da 2 gleichzeitig schreiben wollen
 
Ich hab jetzt grad vor jedem Datenbankzugriff
isDbLockedByCurrentThread() und isDbLockedByOtherThreads()
ausgeben lassen.

soweit ich das gesehen habe, waren diese durchgehen "false".

aber leider stimmen die werte die in die datenbank geschrieben werden nicht...
das ergebnis von getDetails() wird garnicht in die datenbank geschrieben.... diese ist danach noch immer leer. getSps() funktioniert.
und bei getPowerdetails() wird blos das ergebnis aus einer abfrage in die tabelle geschrieben... die ergebnisse der anderen 6 threads/abfragen landen nicht in der db :/
 
Weisst du denn, ob es an der Datenbank oder an dem Netzwerk-Code liegt?
 
Sou, es funktioniert nun...
ich kann dir jetzt ehrlich gesagt nicht mal genau sagen woran es lag...

ich hatte zwischenzeitlich wieder memory-exceptions, hab dann die anzahl an thread verringert und noch mal die datenbank-querys von der rest schnittstelle angepasst...

ich dank dir vielmals... noch stehn ein paar aufgaben an, wird bestimmt nicht das letzte problem gewesen sein ;) jetzt gehts weiter den REST-Serivce mit PUTs und POSTs zu füttern
 
Zurück
Oben