• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 /**
20  * Handy class for starting a new thread that has a looper. The looper can then be
21  * used to create handler classes. Note that start() must still be called.
22  */
23 public class HandlerThread extends Thread {
24     int mPriority;
25     int mTid = -1;
26     Looper mLooper;
27 
HandlerThread(String name)28     public HandlerThread(String name) {
29         super(name);
30         mPriority = Process.THREAD_PRIORITY_DEFAULT;
31     }
32 
33     /**
34      * Constructs a HandlerThread.
35      * @param name
36      * @param priority The priority to run the thread at. The value supplied must be from
37      * {@link android.os.Process} and not from java.lang.Thread.
38      */
HandlerThread(String name, int priority)39     public HandlerThread(String name, int priority) {
40         super(name);
41         mPriority = priority;
42     }
43 
44     /**
45      * Call back method that can be explicitly overridden if needed to execute some
46      * setup before Looper loops.
47      */
onLooperPrepared()48     protected void onLooperPrepared() {
49     }
50 
51     @Override
run()52     public void run() {
53         mTid = Process.myTid();
54         Looper.prepare();
55         synchronized (this) {
56             mLooper = Looper.myLooper();
57             notifyAll();
58         }
59         Process.setThreadPriority(mPriority);
60         onLooperPrepared();
61         Looper.loop();
62         mTid = -1;
63     }
64 
65     /**
66      * This method returns the Looper associated with this thread. If this thread not been started
67      * or for any reason is isAlive() returns false, this method will return null. If this thread
68      * has been started, this method will block until the looper has been initialized.
69      * @return The looper.
70      */
getLooper()71     public Looper getLooper() {
72         if (!isAlive()) {
73             return null;
74         }
75 
76         // If the thread has been started, wait until the looper has been created.
77         synchronized (this) {
78             while (isAlive() && mLooper == null) {
79                 try {
80                     wait();
81                 } catch (InterruptedException e) {
82                 }
83             }
84         }
85         return mLooper;
86     }
87 
88     /**
89      * Quits the handler thread's looper.
90      * <p>
91      * Causes the handler thread's looper to terminate without processing any
92      * more messages in the message queue.
93      * </p><p>
94      * Any attempt to post messages to the queue after the looper is asked to quit will fail.
95      * For example, the {@link Handler#sendMessage(Message)} method will return false.
96      * </p><p class="note">
97      * Using this method may be unsafe because some messages may not be delivered
98      * before the looper terminates.  Consider using {@link #quitSafely} instead to ensure
99      * that all pending work is completed in an orderly manner.
100      * </p>
101      *
102      * @return True if the looper looper has been asked to quit or false if the
103      * thread had not yet started running.
104      *
105      * @see #quitSafely
106      */
quit()107     public boolean quit() {
108         Looper looper = getLooper();
109         if (looper != null) {
110             looper.quit();
111             return true;
112         }
113         return false;
114     }
115 
116     /**
117      * Quits the handler thread's looper safely.
118      * <p>
119      * Causes the handler thread's looper to terminate as soon as all remaining messages
120      * in the message queue that are already due to be delivered have been handled.
121      * Pending delayed messages with due times in the future will not be delivered.
122      * </p><p>
123      * Any attempt to post messages to the queue after the looper is asked to quit will fail.
124      * For example, the {@link Handler#sendMessage(Message)} method will return false.
125      * </p><p>
126      * If the thread has not been started or has finished (that is if
127      * {@link #getLooper} returns null), then false is returned.
128      * Otherwise the looper is asked to quit and true is returned.
129      * </p>
130      *
131      * @return True if the looper looper has been asked to quit or false if the
132      * thread had not yet started running.
133      */
quitSafely()134     public boolean quitSafely() {
135         Looper looper = getLooper();
136         if (looper != null) {
137             looper.quitSafely();
138             return true;
139         }
140         return false;
141     }
142 
143     /**
144      * Returns the identifier of this thread. See Process.myTid().
145      */
getThreadId()146     public int getThreadId() {
147         return mTid;
148     }
149 }
150