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