How to run multiple UI threads in one Activity without ANR?

182 Views Asked by At

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);
     }
    
1

There are 1 best solutions below

4
On

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