Du bist nicht angemeldet.

Werbeanzeige

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 377

Wohnort: Bayern

  • Private Nachricht senden

1

27.11.2014, 19:47

Java Android - Asynchroner Task, globale Variablen

Hi,
hoffe die Überschrift ist nicht zu verwirrend gewählt.
Also ich habe in einer Android App ein Joystick Control, welches bei einer Bewegung mir eine Methode aufruft und die aktuellen x und y Koordinaten übergibt. Diese Werte werden dann an eine weitere Methode übergeben, welche diese Verarbeitet und das Ergebnis per Bluetooth versendet.
Die Werte werden von einem Arduino empfangen. Das Problem ist, das wenn ich den Joystick kurz hin und her Bewege, ca. 200 das Ereignis für die Joystickbewegungsänderung aufgerufen wird, der Arduino so schnell die Daten aber nicht empfangen / verarbeiten kann. Ich möchte daher die Methode zum Verarbeiten maximal zwei mal pro Sekunde aufrufen. Wie setze ich das am besten um?

Wäre es eine gute Idee, sich beim Aufrufen des Joystickspositionsänderungsereignises (schön kurzes Wort :rolleyes:) die aktuelle Zeit zu merken und nur dann die Bluetooth Methode aufzurufen, wenn mindestens 500 Milisekunden vergangen sind? Das Problem ist allerdings, dass ich am liebsten auch bei keiner Positionsänderung die alten Werte im selben Intervall versenden würde. Für die Berechnung brauche ich allerdings Daten aus mehreren globalen Variablen. Wäre ein Thread dann eine Möglichkeit, oder kann es Probleme geben, wenn das Joystickspositionsänderungsereignises "gleichzeitig" mit dem Thread auf die globalen Variablen zugreifen will und diese verändern? Wie könnte ich das geschickter umsetzen, Android würde ja noch ein paar Thread Alternativen liefern...


Edit: Es ist etwas viel Text geworden, vielleicht ist es in Codefassung schneller ersichtlich.

Quellcode

1
2
3
4
5
6
7
8
//Globale Variablen, z.B.
int joystickX, joystickY, messageId,...

//Wird teilweise öfter als alle 500 Millisekunden aufgerufen, bei keiner Benutzerinteraktion gar nicht
public void joystickPositionChange(int x, int y) {//Verändert globale Variablen}

//Soll alle 500 Millisekunden aufgerufen werden
public void sendToAruino() {//Benötigt globale Variablen zur Berechnung}


Danke schon mal für eure Hilfe.


Gruß,
MitgliedXYZ

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »MitgliedXYZ« (27.11.2014, 20:29)


Sacaldur

Community-Fossil

Beiträge: 2 329

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

27.11.2014, 21:37

Bisher wirst du wahrscheinlich schon in irgendeiner Weise wiederholt den aktuellen Wert auslesen. Das musst du nur so abändern, dass diese Auswertung alle 500 Millisekunden (warum nicht alle 100 ms?) passiert und dann aber auch jedes Mal, nicht nur bei Änderungen eine Aktualisierung verschicken.
Ansonsten, sollte die Aktualisierung von einer anderen Stelle aus aufgerufen werden, die du nicht in der Hand hast, wäre eine Art Timer wohl das Mittel der Wahl. Ggf. gibt es da auch synchrone Timer unter Android, ansonsten dürfte ein geschickter Einsatz von synchronized reichen (was aber nur bei einem Zugriff auf veränderbare Objekte relevant sein sollte).

Und ich frage mich, wofür du globale Variablen benötigst...
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 377

Wohnort: Bayern

  • Private Nachricht senden

3

27.11.2014, 21:47

Danke für deine Antwort. Also ich verwende dieses Joystick Control und setze es so ein, wie in dem Tutorial auf der GitHub Seite beschrieben wird. Meine Frage ist nur, wie ich die Werte von da, in meinen anderen Thread bekomme. Mit globalen Variablen habe ich es schon getestet, aber da stürzt mir die App immer ab, die Fehlermeldung habe ich leider gerade nicht mehr da. Wie würdest du vorgehen?

Quellcode

1
2
3
4
5
6
//Das wird in der onCreate() Methode der Aktivity ausgeführt:
        joystick.setOnJoystickMoveListener(new OnJoystickMoveListener() {
            @Override
            public void onValueChanged(int angle, int power, int direction) {//Dieses Methode hier wird aufgerufen bei einer Joystick bewegung
            }
        }, JoystickView.DEFAULT_LOOP_INTERVAL);

BlueCobold

Community-Fossil

Beiträge: 10 872

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

27.11.2014, 21:58

Die Fehlermeldung wäre schon wichtig. So kann man nur spekulieren, dass Du die Werte aus dem anderen Thread an GUI-Controls übergibst, was natürlich Fehler verursacht. Dafür wäre ein Handler.post() oder ein Activity.runOnUiThread() geeignet. In Variablen schreiben darfst Du auch aus anderen Threads problemlos, aber GUI-Elemente wie gesagt nur aus dem UI-Thread heraus verändern.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 377

Wohnort: Bayern

  • Private Nachricht senden

5

29.11.2014, 21:41

Es war wirklich noch an einer Stelle eine GUI Aktuallisierung im Thread, der nicht als GUI-Thread ausgeführt wurde. Jetzt funktioniert es. :S
Bei der Fehlersuche hatte ich mich zu sehr darauf beschränkt den Fehler in den globalen Variablen zu suchen, da ich dachte wenn beide Threads darauf "gleichzeitig" zugreifen gäbe es Probleme, aber anscheinend muss ich mich darum nicht kümmern. Praktisch.
Zur Frage warum alle 500ms, öfter benötige ich zurzeit nicht unbedingt eine Aktualisierung und ich wollte dem Arduino wirklich genug Zeit lassen, die Daten zu verarbeiten. Wobei wenn ich 12 Byte über Bluetooth schicke, welche danach nur noch mit einem bestimmten Wert multipliziert werden müssen, da ist eine halbe Sekunde wohl eine mehr als ausreichende Zeit zum empfangen und berechnen.

BlueCobold

Community-Fossil

Beiträge: 10 872

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

29.11.2014, 22:43

Was heißt bei dir gleichzeitiger Zugriff? Solange nur maximal einer schreibt und alle anderen lediglich lesen, wirst Du da außer bei Listen nie ein Problem haben. Spannend wird's erst, wenn mehrere drauf schreiben und die Ergebnisse dann inkonsistent sein könnten. Exceptions sollte es auch da aber nur relativ selten geben (concurrent modification exceptions bei Listen sind der typischste Fall, der mir üblicherweise begegnet).
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 377

Wohnort: Bayern

  • Private Nachricht senden

7

30.11.2014, 15:35

Bei dieser App schreibt ein Thread und der andere liest nur, außerdem sind es nur Primäre Datentypen, also keine Listen, oder so was. Deine speziellen Anwendungsfällen werde ich hoffentlich noch eine weile nicht verwenden müssen, die Fehlersuche bei so etwas ist dann bestimmt nicht mehr lustig.

8

30.11.2014, 18:04

Was heißt bei dir gleichzeitiger Zugriff? Solange nur maximal einer schreibt und alle anderen lediglich lesen, wirst Du da außer bei Listen nie ein Problem haben. Spannend wird's erst, wenn mehrere drauf schreiben und die Ergebnisse dann inkonsistent sein könnten. Exceptions sollte es auch da aber nur relativ selten geben (concurrent modification exceptions bei Listen sind der typischste Fall, der mir üblicherweise begegnet).
Wenn es sich um 64bit Werte handelt (long und double) muss man allerdings ggf. das Non-atomic Treatment of double and long berücksichtigen. Das Schreiben eines long bzw. double Wertes wird je nach VM in zwei Operationen aufgeteilt. Wenn dann also der schreibende Thread nur die Hälfte geschrieben hat, kann es zu Inkonsistenzen kommen.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Chromanoid« (30.11.2014, 18:11)


BlueCobold

Community-Fossil

Beiträge: 10 872

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

30.11.2014, 20:06

Das gilt aber bei mehreren Schreibern sowieso für alle nicht-trivialen Datentypen. Das hatte ich daher explizit ausgeschlossen in meinem Beitrag.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

10

30.11.2014, 20:34

Das gilt doch aber sogar schon bei einem Schreiber. Es reicht wenn zur gleichen Zeit ein anderer Thread liest.

Werbeanzeige