1 package org.coolreader.crengine; 2 3 import android.os.Handler; 4 import android.util.Log; 5 6 /** 7 * Schedulable cancelable replaceable task. 8 * Can schedule execution of runnable. 9 * When previously scheduled runnable was not yet executed, it's being canceled and being replaced with new one. 10 */ 11 public class DelayedExecutor { 12 13 public static final Logger log = L.create("dt", Log.INFO); 14 15 private boolean isBackground; 16 private Handler handler; 17 private Runnable currentTask; 18 private String name; 19 getHandler()20 private Handler getHandler() { 21 if (handler != null) 22 return handler; 23 if (isBackground) 24 handler = BackgroundThread.getBackgroundHandler(); 25 else 26 handler = BackgroundThread.getGUIHandler(); 27 if (handler == null) 28 throw new RuntimeException("Cannot get handler"); 29 return handler; 30 } 31 createBackground(String name)32 public static DelayedExecutor createBackground(String name) { 33 DelayedExecutor task = new DelayedExecutor(true, name); 34 return task; 35 } 36 createGUI(String name)37 public static DelayedExecutor createGUI(String name) { 38 DelayedExecutor task = new DelayedExecutor(false, name); 39 return task; 40 } 41 42 /** 43 * Run ASAP. 44 * @param task is task to execute. 45 */ post(final Runnable task)46 public void post(final Runnable task) { 47 postDelayed(task, 0L); 48 } 49 50 /** 51 * Run delayed. 52 * @param task is task to execute delayed. 53 * @param delay is delay, milliseconds. 54 */ postDelayed(final Runnable task, final long delay)55 public void postDelayed(final Runnable task, final long delay) { 56 Runnable myTask = new Runnable() { 57 @Override 58 public void run() { 59 try { 60 if (currentTask != null) { 61 log.v("Running task " + toString()); 62 task.run(); 63 log.v("Done task " + toString()); 64 } else { 65 log.w("Skipping probably canceled task " + toString()); 66 } 67 } catch (Exception e) { 68 log.e("Exception while executing task", e); 69 } 70 } 71 72 @Override 73 public String toString() { 74 return name + " " + task.hashCode(); 75 } 76 }; 77 synchronized(this) { 78 if (currentTask != null) { 79 log.d("Cancelling pending task " + currentTask); 80 getHandler().removeCallbacks(currentTask); // cancel pending task, replace with new one 81 } 82 currentTask = myTask; 83 if (delay > 0) { 84 log.d("Posting delayed task " + currentTask + " delay=" + delay); 85 getHandler().postDelayed(currentTask, delay); 86 } else { 87 log.d("Posting task " + currentTask); 88 getHandler().post(currentTask); 89 } 90 } 91 } 92 cancel()93 public void cancel() { 94 synchronized(this) { 95 if (currentTask != null) { 96 log.d("Cancelling pending task " + currentTask); 97 getHandler().removeCallbacks(currentTask); // cancel pending task, replace with new one 98 currentTask = null; 99 } 100 } 101 } 102 DelayedExecutor(boolean isBackground, String name)103 private DelayedExecutor(boolean isBackground, String name) { 104 this.isBackground = isBackground; 105 this.name = name; 106 } 107 } 108