public final class

Threads

extends java.lang.Object

 java.lang.Object

↳androidx.camera.core.impl.utils.Threads

Gradle dependencies

compile group: 'androidx.camera', name: 'camera-core', version: '1.5.0-alpha01'

  • groupId: androidx.camera
  • artifactId: camera-core
  • version: 1.5.0-alpha01

Artifact androidx.camera:camera-core:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

Helpers for java.lang.Threads.

Summary

Methods
public static voidcheckBackgroundThread()

Ensures that we're currently not running in the application's main thread.

public static voidcheckMainThread()

Ensures that we're currently running in the application's main thread.

public static booleanisBackgroundThread()

Returns true if we're currently running on a background thread.

public static booleanisMainThread()

Returns true if we're currently running in the application's main thread.

public static voidrunOnMain(java.lang.Runnable runnable)

Executes the java.lang.Runnable on main thread.

public static voidrunOnMainSync(java.lang.Runnable runnable)

Executes the java.lang.Runnable on main thread and block until the Runnable is complete.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods

public static boolean isMainThread()

Returns true if we're currently running in the application's main thread.

public static boolean isBackgroundThread()

Returns true if we're currently running on a background thread.

public static void checkMainThread()

Ensures that we're currently running in the application's main thread.

public static void checkBackgroundThread()

Ensures that we're currently not running in the application's main thread.

public static void runOnMain(java.lang.Runnable runnable)

Executes the java.lang.Runnable on main thread.

If the caller thread is already main thread, then runnable will be executed immediately. Otherwise, the runnable will be posted to main thread.

public static void runOnMainSync(java.lang.Runnable runnable)

Executes the java.lang.Runnable on main thread and block until the Runnable is complete.

If the caller thread is already main thread, then runnable will be executed immediately. Otherwise, the runnable will be posted to main thread and caller thread will be blocked until the runnable is complete.

A 30 second timeout is basically to prevent unit tests from waiting infinitely if there is any error. Normal flow should not expect this timeout. Basically main thread should not be occupied for too long or an ANR could occur.

Parameters:

runnable: the runnable to execute.

Source

/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.camera.core.impl.utils;

import static androidx.core.util.Preconditions.checkState;

import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Helpers for {@link Thread}s.
 */
public final class Threads {
    private static final long TIMEOUT_RUN_ON_MAIN_MS = 30_000L; // milliseconds

    // Prevent instantiation.
    private Threads() {
    }

    /** Returns true if we're currently running in the application's main thread. */
    public static boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }

    /** Returns true if we're currently running on a background thread. */
    public static boolean isBackgroundThread() {
        return !isMainThread();
    }

    /**
     * Ensures that we're currently running in the application's main thread.
     *
     * @throws IllegalStateException If the caller is not running on the main thread,
     */
    public static void checkMainThread() {
        checkState(isMainThread(), "Not in application's main thread");
    }

    /**
     * Ensures that we're currently not running in the application's main thread.
     *
     * @throws IllegalStateException if the caller is running on the main thread.
     */
    public static void checkBackgroundThread() {
        checkState(isBackgroundThread(), "In application's main thread");
    }
    /**
     * Executes the {@link Runnable} on main thread.
     *
     * <p>If the caller thread is already main thread, then runnable will be executed immediately.
     * Otherwise, the runnable will be posted to main thread.
     */
    public static void runOnMain(@NonNull Runnable runnable) {
        if (isMainThread()) {
            runnable.run();
            return;
        }
        checkState(getMainHandler().post(runnable), "Unable to post to main thread");
    }

    /**
     * Executes the {@link Runnable} on main thread and block until the Runnable is complete.
     *
     * <p>If the caller thread is already main thread, then runnable will be executed immediately.
     * Otherwise, the runnable will be posted to main thread and caller thread will be blocked until
     * the runnable is complete.
     *
     * <p> A 30 second timeout is basically to prevent unit tests from waiting infinitely if
     * there is any error. Normal flow should not expect this timeout. Basically main
     * thread should not be occupied for too long or an ANR could occur.
     *
     * @param runnable the runnable to execute.
     *
     * @throws IllegalStateException if timed out waiting for the posted runnable to complete.
     * @throws InterruptedRuntimeException if the waiting is interrupted.
     */
    public static void runOnMainSync(@NonNull Runnable runnable) {
        if (isMainThread()) {
            runnable.run();
            return;
        }
        // Post to main thread and wait for the completion.
        CountDownLatch latch = new CountDownLatch(1);
        boolean postResult = getMainHandler().post(() -> {
            try {
                runnable.run();
            } finally {
                latch.countDown();
            }
        });
        checkState(postResult, "Unable to post to main thread");
        try {
            if (!latch.await(TIMEOUT_RUN_ON_MAIN_MS, TimeUnit.MILLISECONDS)) {
                throw new IllegalStateException("Timeout to wait main thread execution");
            }
        } catch (InterruptedException e) {
            throw new InterruptedRuntimeException(e);
        }
    }

    @NonNull
    private static Handler getMainHandler() {
        return new Handler(Looper.getMainLooper());
    }
}