JavaFX HTTP Download task im Hintergrund innerhalb GUI

looparda

Top Contributor
Zunächst würde mich noch interessieren:
Ich würde die View an die Properties des Service (anstatt des Tasks) binden. [...] Oder wurde das bewusst gemacht?

Hast du das mal ausprobiert? Würde mich mal interessieren ob das geht. Hintergrund der Frage ist, dass zB die updateMessage() Methode eines Tasks nur in einem FX-Thread aufgerufen werden sollte.
Wenn ich mein ViewModel teste, dann würde ich den Service mocken und könnte mir solche Probleme fern halten.

Wenn ich den Service testen möchte, dann müsste ich den JavaFX Application Thread haben, weil Service an sich sowhol als auch Platform.runLater diesen voraussetzen. So wie hier beschrieben konnte ich einen Service testen. http://blog.buildpath.de/how-to-test-javafx-services/

Wie Du vielleicht dem Thread entnommen hast stehe ich bei Java und JavaFX noch am Anfang
Man kann auch nicht alles auf einmal machen. Man muss es oft erst "naiv" machen, um an die Grenzen zu stoßen, damit man die Vorteile eines anderen Ansatzes sieht und versteht.
 

ralfb1105

Bekanntes Mitglied
Hallo zusammen,

ich habe jetzt noch das letzte Feature "Anzeige Mbps" eingebaut:
Java:
// Variables needed by calculating throughput
            long start = System.nanoTime();
            final double NANOS_PER_SECOND = 1000000000.0;
            final double BYTES_PER_MB = 1024 * 1024;
            double speedInMBps = 0;
            double speedInMbps = 0;

            while ((readByte = bufferedInputStream.read(buffer, 0, 1024)) >= 0 && !isCanceled) {
                bOutputStream.write(buffer, 0, readByte);
                downloaded += readByte;

                final int progress = downloaded;
                listeners.forEach(l -> {
                    l.onUpdateProgress(progress, fileSize);
                    l.onUpdateMessage(String.format("Download: %d / %d Byte ", progress, fileSize));
                });
            }
            LOGGER.info(String.format("Download: %d / %d Byte ", downloaded, fileSize));
            speedInMBps = NANOS_PER_SECOND / BYTES_PER_MB * downloaded / (System.nanoTime() - start);
            speedInMbps = speedInMBps * 8;
            NumberFormat nfFormat = NumberFormat.getInstance();
            nfFormat.setMaximumFractionDigits(2);
            model.setDownloadMbps(String.valueOf(nfFormat.format(speedInMbps)));
            LOGGER.info("Throughput Mbps: " + String.valueOf(nfFormat.format(speedInMbps)));

12237

Ich habe ein paar Infos von anderen Beiträgen verwendet, es macht das was es soll, ob es nun 100% richtig ist kann ich nicht genau sagen da ich keine umfangreichen Tests gemacht habe :p

Da mir dieser Threat mit den vielen hilfreichen Beiträgen, Ideen und Diskussionen sehr viel an Neues und vor allem Wissen zu JavaFX, Listener und der Trennung zwischen GUI, Service und Worker gebracht hat, habe ich mir gedacht das es vielleicht ein ganz gutes Beispiel ist was auch anderen helfen könnte. Aus diesem Grunde habe ich das Projekt auf Github gestellt:
Github DownloadManagerFX

Danke an dieser Stelle auch noch einmal an @Robat , @mihe7 und @looparda für die Beiträge und Ideen!

Gruß

Ralf
 
X

Xyz1

Gast
Ich gebe Dir mal einen Tipp damit bei kleiner buf Größe Deine GUI nicht einfriert:
Java:
long count = 0;

//...

try (/*...*/) {
	int b;
	while ((b = in.read()) != -1) {
		out.write(b);
		count++;
		if (count % (1000 * 1000) == 0) {
			int value = (int) (count / (1000 * 1000));
			x.setValue(value);
		}
	}
}


Ist die Größe bekannt, kannst Du x ja einstellen...
Die Durchschnittswerte errechnen sich aus System.currentTimeMillis, nanoTime herzunehmen ist an dieser Stelle natürlich Schwachsinn.
 

ralfb1105

Bekanntes Mitglied
Ich stehe ehrlich gesagt gerade etwas auf dem Schlauch o_O ich habe jetzt noch nicht so viel getestet, bin auch gerade nur am Tablet, aber ein GUI einfrieren habe ich bis jetzt noch nicht beobachtet. Weiterhin fehlt mir im Moment noch der Hinweis wo genau ich das einbauen sollte. @Tobias-nrw Könntest Du mir bezogen auf den Code noch ein paar mehr Hinweise geben wo genau diese Verbesserung einzusetzen wäre und wann aus Deiner Sicht das GUI einfrieren könnte?

Gruß

Ralf
 
Zuletzt bearbeitet:

ralfb1105

Bekanntes Mitglied
Die Durchschnittswerte errechnen sich aus System.currentTimeMillis, nanoTime herzunehmen ist an dieser Stelle natürlich Schwachsinn.
Ich habe das aus folgendem Thread und war der Meinung das es für meine Zwecke zu gebrauchen wäre, lasse mich natürlich gerne eines besseren belehren, wobei ich den Ausdruck „Schwachsinn“ schon etwas hart finde ...

https://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime

Gruß

Ralf
 
X

Xyz1

Gast
Friert die GUI bei dir ein? Der Download läuft doch parallel zur GUI in einem Background-Thread.
Nicht einfrieren aber es beansprucht die CPU sehr...

Nanotime ist an dieser Stelle einfach überflüssig, da ein Download insgesamt nicht Sekundenbruchteile dauert. Das mit dem "Schwachsinn" war nicht so gemeint.
 

mihe7

Top Contributor
Die Java-Doku ist einfach unübertroffen:
https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime-- hat gesagt.:
Differences in successive calls that span greater than approximately 292 years (2^63 nanoseconds) will not correctly compute elapsed time due to numerical overflow.
 
Zuletzt bearbeitet von einem Moderator:

Ähnliche Java Themen

Neue Themen


Oben