![]() |
BufferedReader in Firemonkey?
Hallo,
ich habe das Problem, dass ich bei einem Android-Projekt die Java-Klasse "BufferedReader" und "InputStreamReader" verwenden möchte, um einen InputStream blockierungsfrei Zeile für Zeile lesen zu können. Ich finde aber im Internet keine Anleitung, wie das geht. Das Problem wurde schon ![]() ![]() Hier mal ein Versuch, die JNI zu verwenden. Stürzt aber bereits beim Konstruktor ab; ich weiß nicht, was falsch ist.
Delphi-Quellcode:
Über Hilfestellungen, insbesondere, wie man beliebige Java-APIs in Delphi per JNI inkludiert, wäre ich sehr dankbar.
type
JBufferedReaderClass = interface(JObjectClass) end; [JavaSignature('java/io/BufferedReader')] JBufferedReader = interface(JObject) function readLine : JString; cdecl; end; TJBufferedReader = class(TJavaGenericImport<JBufferedReaderClass, JBufferedReader>) end; procedure TForm1.Button1Click(Sender: TObject); var x: JBufferedReader; begin x := TJBufferedReader.Create; // <-- Segmentation fault end; |
AW: BufferedReader in Firemonkey?
Nicht
Delphi-Quellcode:
?
var
x: TJBufferedReader; |
AW: BufferedReader in Firemonkey?
Hallo,
wenn ich das verwende, kommt bei folgender Zeile ein Kompilierfehler:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var x: TJBufferedReader; begin x := TJBufferedReader.Create; // [DCC Error] Unit1.pas(50): E2010 Incompatible types: 'TJBufferedReader' and 'JBufferedReader' end; |
AW: BufferedReader in Firemonkey?
Ich denke mir, dass es auch damit zusammenhängen könnte, dass der Konstruktor von BufferedReader ja
![]() Der Konstruktor müsste also wahrlichlich so aussehen:
Delphi-Quellcode:
... allerdings kann ein Interface keinen Konstruktor haben ...
constructor Create(Ain: JReader);
|
AW: BufferedReader in Firemonkey?
Also bei mir geht sowas immer so
Delphi-Quellcode:
function GetConnectivityManager: JConnectivityManager;
var ConnectivityServiceNative: JObject; begin ConnectivityServiceNative := SharedActivityContext.getSystemService( TJContext.JavaClass.CONNECTIVITY_SERVICE ); if not Assigned( ConnectivityServiceNative ) then raise Exception.Create( 'Could not locate Connectivity Service' ); Result := TJConnectivityManager.Wrap( ( ConnectivityServiceNative as ILocalObject ).GetObjectID ); if not Assigned( Result ) then raise Exception.Create( 'Could not access Connectivity Manager' ); end; |
AW: BufferedReader in Firemonkey?
Ich habe den JNI Wrapper mal mit Java2Op erzeugen lassen. Die Konstruktoren sind als init-Methoden implementiert.
Delphi-Quellcode:
{*******************************************************}
{ } { CodeGear Delphi Runtime Library } { Copyright(c) 2014 Embarcadero Technologies, Inc. } { } {*******************************************************} unit Androidapi.JNI.java.io.BufferedReader; interface uses Androidapi.JNIBridge, Androidapi.JNI.JavaTypes; type // ===== Forward declarations ===== JBufferedReader = interface;//java.io.BufferedReader // ===== Interface declarations ===== JBufferedReaderClass = interface(JReaderClass) ['{ED860F80-BCB7-4BC0-977F-95DE9CACE248}'] {class} function init(in_: JReader): JBufferedReader; cdecl; overload; {class} function init(in_: JReader; size: Integer): JBufferedReader; cdecl; overload; end; [JavaSignature('java/io/BufferedReader')] JBufferedReader = interface(JReader) ['{81A25906-BC48-4F21-B1D4-5FDA81218C63}'] procedure close; cdecl; procedure mark(markLimit: Integer); cdecl; function markSupported: Boolean; cdecl; function read: Integer; cdecl; overload; function read(buffer: TJavaArray<Char>; offset: Integer; length: Integer): Integer; cdecl; overload; function readLine: JString; cdecl; function ready: Boolean; cdecl; procedure reset; cdecl; function skip(charCount: Int64): Int64; cdecl; end; TJBufferedReader = class(TJavaGenericImport<JBufferedReaderClass, JBufferedReader>) end; implementation procedure RegisterTypes; begin TRegTypes.RegisterType('Androidapi.JNI.Interfaces.JBufferedReader', TypeInfo(Androidapi.JNI.Interfaces.JBufferedReader)); end; initialization RegisterTypes; end. |
AW: BufferedReader in Firemonkey?
OK und jetzt nochmal zum mitschreiben bitte...
Wofür das ganze "geraffel" mit Java? In der Zeit wo Du das gegoogled hast hättest Du das 3x schon in Delphi programmiert... Versteh ich nicht... Mavarik |
AW: BufferedReader in Firemonkey?
Zitat:
![]() |
AW: BufferedReader in Firemonkey?
Zitat:
Zitat:
Daher meine Antwort schreib es doch schnell in Delphi! Mavarik |
AW: BufferedReader in Firemonkey?
Vielen Dank für den Hinweis mit Java2OP! Ich habe dieses Tool noch nicht gekannt - hätte nicht gedacht, dass das Verwenden der Android API so einfach sein kann :)
Bzgl. "Blockierungsfrei lesen selbst programmieren" - das habe ich schon versucht. Allerdings ging das (wie in StackOverflow beschrieben) nur mit der JInputStream.available() Funktion, die laut Javadokumentation nicht für diesen Zweck verwendet werden soll, da der Wert nur eine grobe Schätzung ist - in der Tat haben manche Geräte wegen der schlechten Schätzung dauerhaft blockiert oder nie gelesen, da available() bei manchen Geräten immer 0 oder immer >0 war. Daher war meine Absicht, den BufferedReader zu verwenden, da das die einzige saubere Möglichkeit ist, einen Stream zuverlässig blockierungsfrei zu lesen. Der Vollständigkeit halber meinen alten Code, der wegen der schlechten Schätzung von available() nicht auf allen Geräten läuft:
Delphi-Quellcode:
Die Dokumentation von Java warnt vor eer Verwendung von available() um blockierungsfreies Lesen zu realisieren:var // of TBufLineJStream buf: TJavaArray<Byte>; FStream: JInputStream; FCurIncompleteString: String; FReadLines: TQueue<String>; const // of TBufLineJStream BufferSize = 65536; procedure TBufLineJStream._ReadFromStream; var c: Char; i, readCount: integer; begin while FStream.available > 0 do begin readCount := FStream.read(buf, 0, BufferSize); for i := 0 to readCount-1 do begin c := Chr(buf.Items[i]); if c = #13 then begin // The line is complete FReadLines.Enqueue(FCurIncompleteString); FCurIncompleteString := ''; end else begin // The line is not complete yet FCurIncompleteString := FCurIncompleteString + c; end; end; end; end; function TBufLineJStream.ReadLineNonBlocking(var outStr: string): boolean; begin _ReadFromStream; result := FReadLines.Count > 0; if result then outStr := FReadLines.Dequeue; end; Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz