![]() |
FMX unbekannten Thread synchronisieren
Hallo Zusammen,
habe folgendes Problem (D11, FMX, IOS):
Delphi-Quellcode:
Wenn man "nicht zulassen" auswählt bei der Abfrage auf dem Smartphone, wird NotificationCenter1PermissionRequestResult aufgerufen.
unit Unit1;
interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Notification, FMX.Controls.Presentation, FMX.StdCtrls; type TForm1 = class(TForm) Button1: TButton; NotificationCenter1: TNotificationCenter; procedure Button1Click(Sender: TObject); procedure NotificationCenter1PermissionRequestResult(Sender: TObject; const AIsGranted: Boolean); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation uses FMX.DialogService; {$R *.fmx} procedure TForm1.Button1Click(Sender: TObject); begin if NotificationCenter1.AuthorizationStatus <> TAuthorizationStatus.Authorized then begin NotificationCenter1.RequestPermission; end; end; procedure TForm1.NotificationCenter1PermissionRequestResult(Sender: TObject; const AIsGranted: Boolean); begin if not AIsGranted then begin TDialogService.ShowMessage ('Die App kann Dir keine Nachrichten senden, da die erforderliche Berechtigung dazu nicht erteilt wurde.'); end; end; end. Das crasht dann mit "Im Projekt Project1 ist eine Exception der Klasse Exception mit der Meldung 'Meldungen müssen im Haupt-UI-Thread angezeigt werden.' aufgetreten." Das kommt vom TDialogService.ShowMessage. Kann ich, und wenn ja, wie, den "unbekannten" Thread der NotificationCenter1PermissionRequestResult aufruft, mit dem Mainthread synchronisieren ? Wenn nein, unter VCL hätte ich jetzt mit einem PostMessage gearbeitet. Gibt es in FMX ein eine äquivalente Möglichkeit dazu ? Vielen Dank schon mal Thomas |
AW: FMX unbekannten Thread synchronisieren
Nur so aus der Hüfte:
Delphi-Quellcode:
TThread.Synchronize(nil,
procedure begin TDialogService.ShowMessage('Die App kann Dir keine Nachrichten senden, da die erforderliche Berechtigung dazu nicht erteilt wurde.'); end; |
AW: FMX unbekannten Thread synchronisieren
Du hättest mit deinen Schüssen aus der Hüfte Billy the Kid erledigt....
Bis auf eine fehlende ) war es perfekt. So klappt es:
Delphi-Quellcode:
procedure TForm1.NotificationCenter1PermissionRequestResult(Sender: TObject;
const AIsGranted: Boolean); begin if not AIsGranted then begin TThread.Synchronize(nil, procedure begin TDialogService.ShowMessage('Die App kann Dir keine Nachrichten senden, da die erforderliche Berechtigung dazu nicht erteilt wurde.'); end); end; end; Vielen Dank. |
AW: FMX unbekannten Thread synchronisieren
Zitat:
Ich mache das gerne so wie unten, mit ForceQueue statt mit Synchronize, um noch mehr auf der sicheren Seite zu sein. Das würde es in allen Thread/NichtTread Fällen gut abkapsel, und man muss sich weniger sorgen machen. In dem Fall mit der Nutzereingabe ist das Timing o.ä. sowieso völlig irrelevant, ob es eine ms mehr oder weniger braucht.
Delphi-Quellcode:
TThread.ForceQueue(nil,
procedure begin TDialogService.ShowMessage('Die App kann Dir keine Nachrichten senden, da die erforderliche Berechtigung dazu nicht erteilt wurde.'); end; |
AW: FMX unbekannten Thread synchronisieren
Bei Queue/ForceQueue mußt du nur aufpassen, wenn du übergreifende Variablen verwendest, dass deren Inhalt (Objekte, Zeiger und bedingt auch dynamische Arrays) zur Ausführungszeit noch vorhanden ist. (oder für den Aufruf vorher kopiert werden)
|
AW: FMX unbekannten Thread synchronisieren
Zitat:
Das ist richtig, und das mache ich standardmässig so nach dem Schema wie unten, und kopiere mir die Variablen lokal, mit dem gleichen Namen, nur mit "A" und "L" unterschiedlich benannt.
Delphi-Quellcode:
Mit dieser Konfiguration gab es noch nie Probleme (Toi, Toi, Toi),
procedure TForm.PressIt( AParam : TMyParameter );
var LParam : TMyParameter; begin LParam := AParm; TThread.ForceQueue(nil, procedure begin TDialogService.ShowMessage( LParam.Message ); end ); end; und ich kann das nur empfehlen :thumb: |
AW: FMX unbekannten Thread synchronisieren
Das geht aber auch nur, wenn TMyParameter keine Klasseninstanz ist, die direkt nach dem Aufruf von PressIt freigegeben wird. Auch eine nachträgliche Änderung des Inhalts von Message könnte sich manchmal in der Anzeige wiederfinden.
Zitat:
|
AW: FMX unbekannten Thread synchronisieren
Ja ein bischen aufpassen muss man schon noch ...
und notfalls einen Clone lokal erzeugen. Deshalb das auch besser noch mit Interfaces benutzen, aber ich glaube wir driften schon etwas ab. |
AW: FMX unbekannten Thread synchronisieren
Jupp, gerade in dem Beispielcode aus Post #6 ist es egal, da LParam und AParam genau gleich behandelt werden.
Aber wie schon genannt, kommt es teilweise auf den jeweiligen Anwendungsfall an, wo die Lösungen auch unterschiedlich ausfallen können. Beispiel: wieder der Code aus #6, aber mit noch einem CONST am Parameter, welcher zufällig ein Record mit mehr als 8 Byte ist. Der Speicher, auf welchen AParam zeigt, der könnte bei Aufruf der Funktion bereits verschwunden oder neu befüllt sein. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:23 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-2025 by Thomas Breitkreuz