19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handy class for starting a new thread that has a looper. The looper can then be 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * used to create handler classes. Note that start() must still be called. 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class HandlerThread extends Thread { 247f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet int mPriority; 257f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet int mTid = -1; 267f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet Looper mLooper; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HandlerThread(String name) { 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(name); 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPriority = Process.THREAD_PRIORITY_DEFAULT; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructs a HandlerThread. 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param name 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param priority The priority to run the thread at. The value supplied must be from 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.os.Process} and not from java.lang.Thread. 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HandlerThread(String name, int priority) { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(name); 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPriority = priority; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4514a9310efd936149c82ecfcc37c7c8308968f67cPin Ting * Call back method that can be explicitly overridden if needed to execute some 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * setup before Looper loops. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onLooperPrepared() { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 518b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown @Override 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTid = Process.myTid(); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper.prepare(); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLooper = Looper.myLooper(); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyAll(); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5959bac03b280115ba843b540298dfb2fbc20491afChih-Chung Chang Process.setThreadPriority(mPriority); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onLooperPrepared(); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper.loop(); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTid = -1; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This method returns the Looper associated with this thread. If this thread not been started 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or for any reason is isAlive() returns false, this method will return null. If this thread 6819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn * has been started, this method will block until the looper has been initialized. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The looper. 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Looper getLooper() { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAlive()) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the thread has been started, wait until the looper has been created. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (isAlive() && mLooper == null) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mLooper; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 878b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 898b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Quits the handler thread's looper. 908b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * <p> 918b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Causes the handler thread's looper to terminate without processing any 928b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * more messages in the message queue. 938b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p> 948b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Any attempt to post messages to the queue after the looper is asked to quit will fail. 958b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * For example, the {@link Handler#sendMessage(Message)} method will return false. 968b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p class="note"> 978b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Using this method may be unsafe because some messages may not be delivered 988b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * before the looper terminates. Consider using {@link #quitSafely} instead to ensure 998b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * that all pending work is completed in an orderly manner. 1008b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p> 1018b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * 1028b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * @return True if the looper looper has been asked to quit or false if the 1038b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * thread had not yet started running. 1048b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * 1058b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * @see #quitSafely 10619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn */ 10719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn public boolean quit() { 10819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn Looper looper = getLooper(); 10919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn if (looper != null) { 11019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn looper.quit(); 11119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn return true; 11219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn } 11319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn return false; 11419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn } 1158b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 1168b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown /** 1178b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Quits the handler thread's looper safely. 1188b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * <p> 1198b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Causes the handler thread's looper to terminate as soon as all remaining messages 1208b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * in the message queue that are already due to be delivered have been handled. 1218b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Pending delayed messages with due times in the future will not be delivered. 1228b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p> 1238b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Any attempt to post messages to the queue after the looper is asked to quit will fail. 1248b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * For example, the {@link Handler#sendMessage(Message)} method will return false. 1258b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p> 1268b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * If the thread has not been started or has finished (that is if 1278b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * {@link #getLooper} returns null), then false is returned. 1288b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Otherwise the looper is asked to quit and true is returned. 1298b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p> 1308b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * 1318b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * @return True if the looper looper has been asked to quit or false if the 1328b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * thread had not yet started running. 1338b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown */ 1348b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown public boolean quitSafely() { 1358b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Looper looper = getLooper(); 1368b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (looper != null) { 1378b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown looper.quitSafely(); 1388b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown return true; 1398b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 1408b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown return false; 1418b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 1428b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 14319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn /** 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the identifier of this thread. See Process.myTid(). 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getThreadId() { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTid; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 150