ThreadUtils.java revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.base; 6 7import android.os.Handler; 8import android.os.Looper; 9import android.os.Process; 10 11import java.util.concurrent.Callable; 12import java.util.concurrent.ExecutionException; 13import java.util.concurrent.FutureTask; 14 15/** 16 * Helper methods to deal with threading related tasks. 17 */ 18public class ThreadUtils { 19 20 /** 21 * Run the supplied Runnable on the main thread. The method will block until 22 * the Runnable completes. 23 * 24 * @param r The Runnable to run. 25 */ 26 public static void runOnUiThreadBlocking(final Runnable r) { 27 if (runningOnUiThread()) { 28 r.run(); 29 } else { 30 FutureTask<Void> task = new FutureTask<Void>(r, null); 31 postOnUiThread(task); 32 try { 33 task.get(); 34 } catch (Exception e) { 35 throw new RuntimeException("Exception occured while waiting for runnable", e); 36 } 37 } 38 } 39 40 /** 41 * Run the supplied Callable on the main thread, wrapping any exceptions in 42 * a RuntimeException. The method will block until the Callable completes. 43 * 44 * @param c The Callable to run 45 * @return The result of the callable 46 */ 47 public static <T> T runOnUiThreadBlockingNoException(Callable<T> c) { 48 try { 49 return runOnUiThreadBlocking(c); 50 } catch (ExecutionException e) { 51 throw new RuntimeException("Error occured waiting for callable", e); 52 } 53 } 54 55 /** 56 * Run the supplied Callable on the main thread, The method will block until 57 * the Callable completes. 58 * 59 * @param c The Callable to run 60 * @return The result of the callable 61 * @throws ExecutionException c's exception 62 */ 63 public static <T> T runOnUiThreadBlocking(Callable<T> c) throws ExecutionException { 64 FutureTask<T> task = new FutureTask<T>(c); 65 runOnUiThread(task); 66 try { 67 return task.get(); 68 } catch (InterruptedException e) { 69 throw new RuntimeException("Interrupted waiting for callable", e); 70 } 71 } 72 73 /** 74 * Run the supplied FutureTask on the main thread. The method will block 75 * only if the current thread is the main thread. 76 * 77 * @param task The FutureTask to run 78 * @return The queried task (to aid inline construction) 79 */ 80 public static <T> FutureTask<T> runOnUiThread(FutureTask<T> task) { 81 if (runningOnUiThread()) { 82 task.run(); 83 } else { 84 postOnUiThread(task); 85 } 86 return task; 87 } 88 89 /** 90 * Run the supplied Callable on the main thread. The method will block 91 * only if the current thread is the main thread. 92 * 93 * @param c The Callable to run 94 * @return A FutureTask wrapping the callable to retrieve results 95 */ 96 public static <T> FutureTask<T> runOnUiThread(Callable<T> c) { 97 return runOnUiThread(new FutureTask<T>(c)); 98 } 99 100 /** 101 * Run the supplied Runnable on the main thread. The method will block 102 * only if the current thread is the main thread. 103 * 104 * @param r The Runnable to run 105 */ 106 public static void runOnUiThread(Runnable r) { 107 if (runningOnUiThread()) { 108 r.run(); 109 } else { 110 LazyHolder.sUiThreadHandler.post(r); 111 } 112 } 113 114 /** 115 * Post the supplied FutureTask to run on the main thread. The method will 116 * not block, even if called on the UI thread. 117 * 118 * @param task The FutureTask to run 119 * @return The queried task (to aid inline construction) 120 */ 121 public static <T> FutureTask<T> postOnUiThread(FutureTask<T> task) { 122 LazyHolder.sUiThreadHandler.post(task); 123 return task; 124 } 125 126 /** 127 * Post the supplied Runnable to run on the main thread. The method will 128 * not block, even if called on the UI thread. 129 * 130 * @param task The Runnable to run 131 */ 132 public static void postOnUiThread(Runnable r) { 133 LazyHolder.sUiThreadHandler.post(r); 134 } 135 136 /** 137 * Asserts that the current thread is running on the main thread. 138 */ 139 public static void assertOnUiThread() { 140 assert runningOnUiThread(); 141 } 142 143 /** 144 * @return true iff the current thread is the main (UI) thread. 145 */ 146 public static boolean runningOnUiThread() { 147 return Looper.getMainLooper() == Looper.myLooper(); 148 } 149 150 /** 151 * Set thread priority to audio. 152 */ 153 @CalledByNative 154 public static void setThreadPriorityAudio(int tid) { 155 Process.setThreadPriority(tid, Process.THREAD_PRIORITY_AUDIO); 156 } 157 158 private static class LazyHolder { 159 private static Handler sUiThreadHandler = new Handler(Looper.getMainLooper()); 160 } 161} 162