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 196a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Suslaimport android.annotation.NonNull; 206a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Suslaimport android.annotation.Nullable; 216a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handy class for starting a new thread that has a looper. The looper can then be 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * used to create handler classes. Note that start() must still be called. 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class HandlerThread extends Thread { 277f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet int mPriority; 287f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet int mTid = -1; 297f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet Looper mLooper; 306a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla private @Nullable Handler mHandler; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HandlerThread(String name) { 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(name); 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPriority = Process.THREAD_PRIORITY_DEFAULT; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructs a HandlerThread. 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param name 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param priority The priority to run the thread at. The value supplied must be from 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.os.Process} and not from java.lang.Thread. 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HandlerThread(String name, int priority) { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(name); 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPriority = priority; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4914a9310efd936149c82ecfcc37c7c8308968f67cPin Ting * Call back method that can be explicitly overridden if needed to execute some 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * setup before Looper loops. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onLooperPrepared() { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 558b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown @Override 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTid = Process.myTid(); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper.prepare(); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLooper = Looper.myLooper(); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyAll(); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359bac03b280115ba843b540298dfb2fbc20491afChih-Chung Chang Process.setThreadPriority(mPriority); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onLooperPrepared(); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper.loop(); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTid = -1; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This method returns the Looper associated with this thread. If this thread not been started 716caa45286553b4aabe9f65e8c680035602f6a7b6Jeremy Klein * or for any reason isAlive() returns false, this method will return null. If this thread 7219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn * has been started, this method will block until the looper has been initialized. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The looper. 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Looper getLooper() { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAlive()) { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the thread has been started, wait until the looper has been created. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (isAlive() && mLooper == null) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mLooper; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 918b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 936a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla * @return a shared {@link Handler} associated with this thread 946a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla * @hide 956a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla */ 966a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla @NonNull 976a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla public Handler getThreadHandler() { 986a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla if (mHandler == null) { 996a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla mHandler = new Handler(getLooper()); 1006a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla } 1016a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla return mHandler; 1026a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla } 1036a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla 1046a7006a9683ba5a79ca338050c7c50b346b04de0Eugene Susla /** 1058b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Quits the handler thread's looper. 1068b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * <p> 1078b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Causes the handler thread's looper to terminate without processing any 1088b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * more messages in the message queue. 1098b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p> 1108b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Any attempt to post messages to the queue after the looper is asked to quit will fail. 1118b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * For example, the {@link Handler#sendMessage(Message)} method will return false. 1128b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p class="note"> 1138b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Using this method may be unsafe because some messages may not be delivered 1148b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * before the looper terminates. Consider using {@link #quitSafely} instead to ensure 1158b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * that all pending work is completed in an orderly manner. 1168b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p> 1178b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * 1188b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * @return True if the looper looper has been asked to quit or false if the 1198b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * thread had not yet started running. 1208b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * 1218b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * @see #quitSafely 12219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn */ 12319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn public boolean quit() { 12419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn Looper looper = getLooper(); 12519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn if (looper != null) { 12619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn looper.quit(); 12719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn return true; 12819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn } 12919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn return false; 13019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn } 1318b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 1328b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown /** 1338b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Quits the handler thread's looper safely. 1348b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * <p> 1358b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Causes the handler thread's looper to terminate as soon as all remaining messages 1368b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * in the message queue that are already due to be delivered have been handled. 1378b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Pending delayed messages with due times in the future will not be delivered. 1388b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p> 1398b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Any attempt to post messages to the queue after the looper is asked to quit will fail. 1408b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * For example, the {@link Handler#sendMessage(Message)} method will return false. 1418b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p> 1428b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * If the thread has not been started or has finished (that is if 1438b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * {@link #getLooper} returns null), then false is returned. 1448b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Otherwise the looper is asked to quit and true is returned. 1458b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p> 1468b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * 1478b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * @return True if the looper looper has been asked to quit or false if the 1488b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * thread had not yet started running. 1498b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown */ 1508b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown public boolean quitSafely() { 1518b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Looper looper = getLooper(); 1528b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (looper != null) { 1538b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown looper.quitSafely(); 1548b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown return true; 1558b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 1568b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown return false; 1578b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 1588b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 15919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn /** 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the identifier of this thread. See Process.myTid(). 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getThreadId() { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTid; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 166