-1

I want to create a monitoring application and their updated UI every second. for example I have 10 textView for display timing and 10 Progress bar to set some progress to display and 6 timers for display time like a stopwatch. all things in the same activity and its run also at the same time.

But When I used ScheduledExecutorService UI stuck and the application going to not respond. how to Implement all things perfectly without ANR?

  • Here is My code update textView Timer in the thread

         private void getLiveUpdate() {
         ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
         MyTimerTask myTimerTask = new MyTimerTask(() -> {
             runOnUiThread(() -> {
                 getSetData();
                 getTime(binding.tvCurrentDate);
                 setRv_channels(switchGroup1, Utills.switchModels1, binding.rvChannelsMain);
                 setRv_channels(switchGroup2, Utills.switchModels2, binding.rvChannelsMain1);
                 setRv_channels(switchGroup3, Utills.switchModels3, binding.rvChannelsMai2);
    
                 if (isOtOn) {
                     binding.tvOtOffTime.setText(timee(otStartCounter));
                     otStartCounter++;
                 }
                 if (isPatientIn) {
                     binding.tvPOutTime.setText(timee(patientInCounter));
                     patientInCounter++;
                 }
                 if (isSurgIn) {
                     binding.tvSugOutTime.setText(timee(surgeonTimeCounter));
                     surgeonTimeCounter++;
                 }
                 if (isAnaeIn) {
                     binding.tvAnafTime.setText(timee(anaeTimeCounter));
                     anaeTimeCounter++;
                 }
                 if (isSurgeryStart) {
                     binding.tvSurgeryTime.setText(timee(surgeryTimeConunter));
                     surgeryTimeConunter++;
                 }
                 if (isAnaeStart) {
                     binding.tvAneTime.setText(timee(anaeStartTimeConunter));
                     anaeStartTimeConunter++;
                 }
    
    
             });
         });
         scheduler.scheduleAtFixedRate(myTimerTask, 0, 1, TimeUnit.SECONDS);
    
    
     }
    
         private String timee(int seconds) {
         int hours = seconds / 3600;
         int minutes = (seconds % 3600) / 60;
         int secs = seconds % 60;
         return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, secs);
     }
    
jcredking
  • 314
  • 1
  • 10
  • Removed `android-studio` tag as that tag is used for questions/issues regarding the Android Studio product. This question has nothing to do with Android Studio. – David Wasser Jan 19 '23 at 13:20
  • If you are getting ANR, that means that you are doing too much work on (or blocking) the main (UI) thread. Are you doing something like `sleep` on the main (UI) thread? Show us some code please. – David Wasser Jan 19 '23 at 13:22
  • @DavidWasser I Added Some code please check it – jcredking Jan 20 '23 at 05:30
  • What do `getSetData()` and `getTime()` do? – David Wasser Jan 20 '23 at 07:28
  • @DavidWasser `getTime()` is set the current date and time with seconds in this format `EE, d MMM yyyy HH:mm:ss aaa` and `getSetData()` set 10 progress bar to set progress which gets value from API and API call every second from background service. – jcredking Jan 20 '23 at 08:35
  • Well, I don't see any code here that would generate an ANR. An ANR occurs when your maijn (UI) thread is blocked (ie: using it for file or network I/O, or calling `sleep()`, or if you have code that is synchronized on a locked object) OR when your main (UI) thread is so busy that the Android framework cannot service the display updates fast enough. You need to dig into your code and see what you are doing that would cause an ANR. – David Wasser Jan 22 '23 at 14:17

1 Answers1

2

UI thread is one and only, there is no such thing as "multiple UI thread"

if you are performing some actions in separated thread and want to show (partial) results in GUI you have to run GUI-drawing-related code (e.g. textView.setText(...)) in this one and only UI thread. easiest way is to use Handler with MainLooper - its called "main", because UI thread is one and only mandatory working thread, you may not thread your app/code at all. so you can get access to it by some static refrerences, thus below may be pasted literally anywhere in any thread

Handler(Looper.getMainLooper()).post {
    // UI related code
}

still if you want to change text in some TextView, which is created/referenced in UI thread only you have to pass reference to it to this "another thread" and use this reference inside Runnable posted for Handler with main Looper

snachmsm
  • 17,866
  • 3
  • 32
  • 74
  • 1
    Using `Handler` like this is not necessary. You can call `post()` on any `View` or use `runOnUiThread()` you want to run code on the main (UI) thread. – David Wasser Jan 19 '23 at 13:23
  • right, just get used to this pattern as oftenly I'm not calling "UI related code" in `Activity` so `runOnUiThread` isn't availabe and I do want to change multiple `View`s at once, then I'm passing single `Runnable` instead of bunch of related `View`s/references – snachmsm Jan 19 '23 at 14:25
  • You can post any code to a `View`. It isn't restricted to code that deals with that `View`. This is just another way to call `runOnUiThread()`. – David Wasser Jan 19 '23 at 15:34
  • @snachmsm I used your method but UI still stuck after some time – jcredking Jan 20 '23 at 07:09