notifyAll/wait falsch benutzt?

  • Hallo zusammen!


    Mein erster Beitrag und dann noch gleich eine Frage ;)


    Folgendes:
    Ich will eine App entwickeln die periodisch Screenshots macht.
    D.h. meine screenshot-Funktion muss alle X Sekunden aufgerufen werden.
    Ich dachte, ich implementiere das ganze als AsyncTask.



    Die Idee dahinter ist, dass der MainThread screenshot() aufruft.
    Dann wird 1 Sekunde in einem 2. Thread gewartet.
    Dann das ganze erstmal nur 10 Mal. (Später solls solang gehen, bis erneut ein Button gedrückt wird. Aber erstmal kleine Schritte)


    Das Problem könnte m.M.n an 2 Stellen liegen:
    1.) notifyAll befindet sich in einer inneren Klasse und weckt damit das wait nicht auf.
    2.) das wait ist immer noch im MainThread. Trotzdem sollte die App aber nur für 1 Sekunde hängen (und nicht dauerhaft), da dann das notify kommt, oder?


    Wenn 2.) zutrifft, wie lager ich es richtig aus?
    Wenn ich es auslager, dann muss die screenshot()-Funktion ja auch raus. Aber wie greife ich von außerhalb auf die aktuelle View des MainThreads zu?
    Alle meine Versuche sind bisher in dem Bereich gescheitert...



    Bin für jede Hilfe dankbar, da ich schon langsam am Verzweifeln bin.. :-/


    DANKE
    Gruß

    Crown

  • Ich glaube, deine While-Schleife an sich möchtest du so gar nicht haben.


    So wie ich die Sache jetzt verstehe, werden alle 10 Sekunden Screenshots gemacht – bei blockiertem GUI.
    In der gefühlten Nanosekunde zwischen notifyAll(), dem Ende von wait() und dem erneuten Beginn von wait() kann der User schlicht überhaupt nichts in der GUI tun. Du wirst also 10x den identischen Screenshot haben.


    Wäre es nicht sinnvoller, du packst diese While-Schleife in den AsyncTask und machst dort einfach so lange die Bilder, so dass das GUI vernünftig weiterlaufen kann?

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • matthias: schon mal danke dafür. Nur das Problem ist, er kommt ja nichtmal dazu i hochzuzählen, da er ja im wait() ewig hängt.



    @Lucas de Vil: Du ahst recht, natürlich soll der benutzer weiterhin die GUI bedienen können.
    Habs also mal ausgelagert:


    Nur jetzt die Frage warum wird kein Screenshot gemacht? Es scheint mir, dass onPreExecute gar nicht ausgeführt wird.
    Warum nicht?
    Ich bin mir auch nich sicher, ob die aktuelle Main-View richtig übergeben wird mit dem Aufruf:
    screenshot(new MainThread().findViewById(android.R.id.content));


    Es kommt jedenfalls keine Fehlermeldung. Könnte aber auch dadran liegen, dass die Funktion gar nicht aufgerufen wird

  • Hoi,


    joa das wait hab ich einfach überlesen ^^ hast natürlich recht ... glaub der wacht au deshalb nicht mehr auf, da du das im AsyncTask machst und der vermutlich den Main-Thread gar nicht aufwecken darf, aber egal


    Warum machst du das eigentlich im PreExecute? Wirf es doch einfach als erste Zeile in die doInBackground ... Deine Main Activity einfach mit new neu instanzieren ist wohl auch keine gute Idee, übergib dem AsyncTask beim erstellen doch einfach den Context, also von der Activity aus this, dann kannst du vom Context aus die View holen.



    Gruß,
    matze

  • man kann/darf doch gar nicht in doInBackground auf die UI zugreifen. Und genau das mache ich aber mit screenshot().
    UI zugriffe sind nur in onPostExecute und in onPreExecute erlaubt.
    Daher kann ich den Funktionsaufruf nicht in doInBackground machen.


    selbst wenn ich den Context übergebe, gibt es ja immer noch das Problem, dass onPreExecute nicht ausgeführt wird.

  • Hi,


    wir denken irgendwie aneinander vorbei ...


    Das onPreExecution dient ja dazu, einmalig Initialisierungen vorzunehmen, die dann im doInBackground gebraucht werden. Dein Task sieht eher so aus, als würde der für eine einmalige Sache ausgelegt sein, anstatt tatsächlich nebenläufig etwas alle 10 Sekunden zu tun.


    Eigentlich müsstest du doch eine Schleife basteln, die für deinen ersten kleinen Schritt einen Zähler bis 10 zählt. Innerhalb der Schleife startest du einen Handler, dem du in einem Runnable deine UI Aufgabe gibst. Die führt der Handler dann im MainThread aus. Dann sagst du ihm schlaf 10 Sekunden, noch innerhalb der Schleife.



    Also sowas die Richtung



    Wobei ich mich frag, ob es tatsächlich notwendig ist, jedes mal eine neue Instanz von CaptureScreen zu erzeugen ...
    Und warum eigentlich android.R.id.content? ist das nicht die falsche Klasse R? Die müsste doch eigentlich irgendwo in my.own.package.R liegen.


    Gruß,
    matze

  • sehr geil! DANKE matthias!
    haben tatsächlich etwas aneinander vorbei gedacht.


    Also es funktioniert jetzt, dass alle X Sekunden ein Screenshot gemacht wird.



    mit dem android.R.id.content...
    Ich erweiter die ApiDemo von Google Android. Die App wo es zu eigentlich fast jeder Funktion ein Beispiel gibt.
    Grund ist einfach, dass ich so nicht die ganzen Test-Szenarien wie OpenGL und Activity-Wechsel selbst programmieren muss.


    Laut StackOverflow bekommt man damit die Elemente der RootView.


    das komische ist, dass ich in my.own.package.R.id.content keinen content habe, den ich ansprechen könnte.
    Und ich weiß nicht, wie die Entwickler von ApiDemo die content genannt haben. Ich weiß auch nicht wo ich das nachlesen könnte ;)



    Ich glaube daran hängt auch mein folge Fehler.
    Es macht zwar die Screenshots, aber obwoh ich innerhalb der Zeit die View wechsel, wird der Screenshot immer noch von der View gemacht, von der die Funktion gestartet wurde...

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!