Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Delphi Android ANR Wait (https://www.delphipraxis.net/216180-android-anr-wait.html)

Gruber_Hans_12345 14. Nov 2024 10:25

Android ANR Wait
 
Hallo noch eine Frage, wenn so eine ANR Meldung auftaucht (wenn der UI Thread mal blockiert ist) dann kommt ja die Frage ob man warten oder schließen muss.

Ist das normal wenn man da auf warten klickt, und die Anwendung nichts mehr tut, also wirklich total idle ist - die Meldung immer wieder kommt?
Also die App macht schon gar nichts mehr und man klickt dann 10mal auf warten - so alle 10 Sekunden ca.

(Ich weiß man sollte es gar nicht so weit kommen lassen das die erste ANR kommt)
Nur ich frage mich wozu der warten Button dann da ist.
Oder geht da einfach in Delphi irgendwo ein Befehl ab, damit er das ANR System wieder zurücksetzt?

Olli73 14. Nov 2024 18:01

AW: Android ANR Wait
 
Bist du dir sicher, dass die Anwendung wirklich "idle" ist? Sie reagiert also auf Nutzereingaben?

Ansonsten, wenn die App z.B. auf eine Datenbank-Antwort oder auf eine Response von einen (HTTTP-)Request wartet, reagiert sie halt eben auf Nichts, obwohl sie nahezu nichts macht. Und weder das Betriebssystem noch der Anwender weiß, ob sie sich aufgehangen hat oder irgendwann doch noch fertig wird.

Das kann man nur damit umgehen, indem man Threads oder asynchrone Aufrufe verwendet.

Gruber_Hans_12345 18. Nov 2024 08:16

AW: Android ANR Wait
 
Ja ich bin mir da sehr sehr sicher, da ich einfach im Button Klick einen sleep(10000) mache.
Einmal den Button geklickt da gibts einmal oder auch zweimal diese Meldung die auch gerechtfertigt ist, aber danach liegt das Handy einfach nur da und ich tue nichts mehr.

fisipjm 18. Nov 2024 13:03

AW: Android ANR Wait
 
Zitat:

Zitat von Gruber_Hans_12345 (Beitrag 1543181)
Ja ich bin mir da sehr sehr sicher, da ich einfach im Button Klick einen sleep(10000) mache.
Einmal den Button geklickt da gibts einmal oder auch zweimal diese Meldung die auch gerechtfertigt ist, aber danach liegt das Handy einfach nur da und ich tue nichts mehr.

Leider völlig normales verhalten bei einer Delphi Android APP. Einmal im ANR Screen angekommen gibt's kein zurück mehr. Deshalb lagere ich so gut wie jede Aktion die nicht unbedingt in den Hauptthread muss mit einem darüberliegenden Loading Screen in einen extra Thread aus.

Rollo62 19. Nov 2024 07:08

AW: Android ANR Wait
 
Also bei mir gehts danach in der Regel weiter, das kommt bei mir eigentlich nur, wenn Debugging ausgewählt ist.
Im Release kommt das, wenn es einen groben Fehler gab, danach geht es dann meistens nicht weiter und crasht.

https://developer.android.com/topic/...tals/anr?hl=de
Zitat:

Ein ANR-Fehler wird für Ihre App ausgelöst, wenn eine der folgenden Bedingungen eintritt:

Zeitüberschreitung bei der Eingabeversand:Ihre App hat auf eine Eingabe nicht reagiert. (z. B. Tastendruck oder Bildschirmberührung) innerhalb von 5 Sekunden.
Dienst wird ausgeführt:Wenn ein von Ihrer App deklarierter Dienst nicht abgeschlossen werden kann Ausführung von Service.onCreate() und Service.onStartCommand()/Service.onBind() innerhalb weniger Sekunden.
Service.startForeground() nicht aufgerufen:Wenn Ihre App Context.startForegroundService(), um einen neuen Dienst im Vordergrund zu starten, aber der Dienst ruft startForeground() dann nicht innerhalb von 5 Sekunden auf.
Übertragung der Absicht:Wenn eine BroadcastReceiver Ausführung innerhalb eines festgelegten Zeitraums nicht abgeschlossen hat. Wenn die App über Aktivität im Vordergrund liegt, beträgt dieses Zeitlimit 5 Sekunden.
Interaktionen mit Job Scheduler: Wenn ein JobService gibt nicht zurück von JobService.onStartJob() oder JobService.onStopJob() innerhalb weniger oder wenn ein vom Nutzer initiierter Job startet und Ihre App ruft nicht innerhalb weniger Sekunden JobService.setNotification() auf Sekunden, nachdem JobService.onStartJob() aufgerufen wurde. Für App-Targeting Bei Android 13 und niedriger sind die ANR-Fehler im Hintergrund und werden nicht an die App gemeldet. Bei Apps, die auf Android 14 und höher ausgerichtet sind, sind die ANR-Fehler explizit und werden an die App gemeldet.

Wenn in deiner App ANR-Fehler auftreten, kannst du anhand der Anleitung in diesem Artikel Folgendes tun: Problem zu diagnostizieren und zu beheben.
Wenn Du das über einen TTimer simulierst, dann könnte es daran liegen, dass TTimer nicht im Hintergrund funktionieren.
Vielleicht muss man das anders simulieren, oder einen nativen Timer nehmen.

wjjw 19. Nov 2024 09:36

AW: Android ANR Wait
 
Hallo!

Hab das selbe Problem.
Ein einfaches Sleep(5000) bringt die Endlosmeldung (alle 5 Sekunden) "Projekt reagiert nicht - App schließen / Warten"!

Einfacher Code zum Testen:
Delphi-Quellcode:
procedure TForm1.Sl(sec: Integer);
var s: String;
    t1, t2: TDateTime;
begin
   t1 := Now;
   Sleep(sec * 1000);
   t2 := Now;
   s := 'Sleep(' + IntToStr(sec * 1000) + '): ';
   s := s + FormatDateTime('h:n:s.z', t1);
   s := s + ' to ';
   s := s + FormatDateTime('h:n:s.z', t2);
   Memo1.Lines.Add(s);
end;
Ergebnisse:
Sl(4) -> Memo1 -> 10:18:00.000 to 10:18:04.000
Sl(8) -> Memo1 -> 10.18.00.000 to 10.18:05.096 (also wird nach 5 Sekunden abgebrochen statt der gewünschter 8)!

Das heisst auch er bricht in Mitten der Sleep-Funktion nach 5 Sekunden ab.
Ich frage mich nur wenn ein Code "unerwarteterweise" länger als 5 Sekunden läuft, welche unerwarteten Effekte das haben kann.
Bei "erwarteten" Aktionen die länger dauern können eh kein Problem.

Und das heisst das das alles war nur irgendwie länger dauern KÖNNTE ich es als TThread / TTask implementieren muss.
Das es für diesen Zweck nichts einfacheres und sicheres gibt.
Es wäre ja auch ok wenn der Dialog nicht periodisch immer wieder kommen würde, wenn doch es die Aktion bereits beendet ist ->
ODER soll ich statt Sleep(8000) ein Sleep(4000) und danach ein Sleep(4000) einbauen (simpel dargestellt)?? :-D

Ich könnte die ganze App in einen 2. Thread packen... :wink:

Rollo62 19. Nov 2024 10:21

AW: Android ANR Wait
 
Zitat:

Zitat von wjjw (Beitrag 1543216)
... Ich könnte die ganze App in einen 2. Thread packen... :wink:

Man sollte längerdauernde Tasks in einen Thread packen.
Wie gesagt, bei mir passiert das häufig beim Debuggen, wo ich verstehen kann dass die Debugger features schonmal blockieren können.
Die App selber sollte besser nicht blockieren.

wjjw 19. Nov 2024 10:34

AW: Android ANR Wait
 
Hab mir die Delphi-Doku diesbezüglich nochmal angesehen.
Sogar deren Beispiele funktionieren nicht...
Das Bespiel in Android sage auch das die App nicht reagiert (nach WaitAll auf 2 Tasks - 8 Sekunden). :o

https://docwiki.embarcadero.com/RADS...amming_Library

Delphi-Quellcode:
procedure TForm1.MyButtonClick(Sender: TObject);
var
  tasks: array of ITask;
  value: Integer;
begin
  Setlength (tasks ,2);
  value := 0;

 tasks[0] := TTask.Create (procedure ()
  begin
   sleep(3000);
   TInterlocked.Add (value, 3000);
  end);
 tasks[0].Start;

 tasks[1] := TTask.Create (procedure ()
   begin
   sleep (5000);
   TInterlocked.Add (value, 5000);
 end);
 tasks[1].Start;
 
 TTask.WaitForAll(tasks);
 ShowMessage ('All done: ' + value.ToString);
end;

Rollo62 19. Nov 2024 11:59

AW: Android ANR Wait
 
Das Beispiel "TTask from the Parallel Programming Library" ist ja nicht Android-spezifisch, sondern eher allgemein auf Windows gemünzt.

Es ist so, dass eine Funktion im Hintergrund noch eine Zeit weiter ausgeführt wird, bevor Android/Apple doese wirklich hart killen.
Das ist mehr für Aufräumarbeiten gedacht, bevor die App schliest, aber nicht zur permanenten Hintergrundverarbeitung.
So einfach ist das bei den Mobilen nicht mehr.

Vielleicht hakt es beim Sleep, was Android negativ aufstößt, Du könntest mal folgendes stattdessen versuchen, bei dem der Task aktiv bleibt.

Delphi-Quellcode:
Uses
    ...
    System.DateUtils
    ...

procedure TForm1.Button1Click(Sender: TObject);
var
 aTask: ITask;
begin
 aTask := TTask.Create(
   procedure
   var
       LDelay : TDateTime;
       LCount : Int64;
   begin
     LDelay := Now;

//     sleep (3000); // 3 seconds

     LCount := 0;

     while MilliSecondsBetween( Now, LDelay ) < 5000 do
     begin
         //Loope brutalst hier herum, zähle mal zum Spass
         Inc( LCount );
     end;

     TThread.Synchronize(TThread.Current,
       procedure
       begin
         ShowMessage ('Hello ' + LCount.ToString );
       end);
   end);
   aTask.Start;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:32 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