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