libutils android::Thread 介绍

android::Thread 是 Android libutils 库中的 轻量级 C++ 线程封装,主要用于 Native 层的多线程管理,在 AudioFlinger、SurfaceFlinger、Camera HAL 等组件中广泛使用。

  • 基于 pthread 进行封装,提供 C++ 线程管理能力。
  • 支持 run() 方式启动线程,无需手动调用 pthread_create
  • 通过 threadLoop() 实现任务循环,适用于长时间运行的任务。
  • 提供 requestExit() 进行优雅退出,避免 pthread_cancel() 造成资源泄露。
  • 继承 RefBase,支持 sp<> 智能指针管理线程生命周期。

android::Thread 的使用

1. 继承 android::Thread 创建自定义线程

覆写 threadLoop 虚函数 ,返回 true 表示继续循环,false 表示退出线程 ,还需要注意保持android::Thread 对象存活,如果被回收 ,threadLoop 函数即使返回 true ,线程也会退出

cpp 复制代码
#include <utils/Thread.h>
#include <utils/Log.h>

using namespace android;

class MyThread : public Thread {
public:
    MyThread() {}
    virtual ~MyThread() {}

    virtual bool threadLoop() override {
        ALOGI("Thread running...");
        sleep(1);  // 模拟任务
        return true;  
    }
};

2. 启动线程

cpp 复制代码
sp<MyThread> myThread = new MyThread();
myThread->run("MyWorkerThread");  // 线程启动

3. 请求线程退出

cpp 复制代码
myThread->requestExit();  // 仅标记退出
myThread->join();  // 等待线程真正退出

源码分析

android::Thread 构造函数

cpp 复制代码
explicit            Thread(bool canCallJava = true);
// canCallJava 默认为 true 
Thread::Thread(bool canCallJava)
    : mCanCallJava(canCallJava),
      mThread(thread_id_t(-1)),
      mLock("Thread::mLock"),
      mStatus(OK),
      mExitPending(false),
      mRunning(false),
      mTid(-1)
{
}

// run 方法 
// name : 线程名字 
// priority : 线程优先级 ,默认 PRIORITY_DEFAULT
// stack : 线程栈大小 ,默认为 0
virtual status_t run(const char* name,
                        int32_t priority = PRIORITY_DEFAULT,
                        size_t stack = 0);

status_t Thread::run(const char* name, int32_t priority, size_t stack)
{
    LOG_ALWAYS_FATAL_IF(name == nullptr, "thread name not provided to Thread::run");

    Mutex::Autolock _l(mLock);
    // mRunning 默认为 false ,只能调用一次 run 方法 
    if (mRunning) {
        // thread already started
        return INVALID_OPERATION;
    }
    
    mStatus = OK;
    mExitPending = false;
    mThread = thread_id_t(-1);

    // 自己持有自己的强引用
    mHoldSelf = sp<Thread>::fromExisting(this);
    mRunning = true;

    bool res;
    // mCanCallJava 默认为 true ,调用 createThreadEtc 创建线程 
    if (mCanCallJava) {
        // _threadLoop 函数指针,线程启动要执行的函数
        res = createThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    } else {
        res = androidCreateRawThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    }
    // 如果线程启动失败 
    if (res == false) {
        mStatus = UNKNOWN_ERROR;   
        mRunning = false;
        mThread = thread_id_t(-1);
        mHoldSelf.clear();  // 移除自身引用,让 thread 对象可以回收 

        return UNKNOWN_ERROR; // 返回错误 
    }
    return OK;
}


// entryFunction : 为函数指针 _threadLoop 线程入口函数 
// userData : 线程函数的的参数 ,传递的是 android::Thread this 指针 
// name : 为线程名字 ,默认为 android:unnamed_thread
// threadPriority : 线程优先级 
// threadStackSize : 线程栈空间大小,默认为 0 
// threadId : 线程 id ,默认为 nullptr 传递的是 android::Thread 成员变量 mThread 
inline bool createThreadEtc(thread_func_t entryFunction,
                            void *userData,
                            const char* threadName = "android:unnamed_thread",
                            int32_t threadPriority = PRIORITY_DEFAULT,
                            size_t threadStackSize = 0,
                            thread_id_t *threadId = nullptr)
{
    return androidCreateThreadEtc(entryFunction, userData, threadName,
        threadPriority, threadStackSize, threadId) ? true : false;
}

// androidCreateThreadEtc 调用 gCreateThreadFn 函数 
int androidCreateThreadEtc(android_thread_func_t entryFunction,
                            void *userData,
                            const char* threadName,
                            int32_t threadPriority,
                            size_t threadStackSize,
                            android_thread_id_t *threadId)
{
    return gCreateThreadFn(entryFunction, userData, threadName,
        threadPriority, threadStackSize, threadId);
}



typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
                                        void *userData,
                                        const char* threadName,
                                        int32_t threadPriority,
                                        size_t threadStackSize,
                                        android_thread_id_t *threadId);

// gCreateThreadFn 为静态成员变量,是一个函数 android_create_thread_fn 指针 
// 默认为 androidCreateRawThreadEtc
static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;

// 但是 提供了一个改变 gCreateThreadFn 函数 
void androidSetCreateThreadFunc(android_create_thread_fn func)
{
    gCreateThreadFn = func;
}

android::Thread 默认是能够调用 java 方法的,但是调用 java 需要 android java 虚拟机 。android java 虚拟机是 Zygote 进程启动的 ,所有的 app 进程都是 Zygote fork 的 ,所有才能够运行 java 代码 。

下面是 Zygote 进程启动时启动时,执行的一段代码

cpp 复制代码
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    // 启动 java 虚拟机 
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);
    // 调用 startReg 函数 
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
}

// startReg 函数里面修改了 gCreateThreadFn 静态全局变量 
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
    return 0;
}

// gCreateThreadFn 变为 javaCreateThreadEtc 函数 
/*static*/ int AndroidRuntime::javaCreateThreadEtc(
                                android_thread_func_t entryFunction,
                                void* userData,
                                const char* threadName,
                                int32_t threadPriority,
                                size_t threadStackSize,
                                android_thread_id_t* threadId)
{
    // 创建 3 个 void* 指针 ,分别存储线程入口函数,函数参数,线程名字 
    void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
    int result;

    LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc");

    args[0] = (void*) entryFunction;
    args[1] = userData;
    // threadName 可能是局部变量的字符串,需要 strdup 复制到堆内存,避免访问失效数据
    args[2] = (void*) strdup(threadName);   // javaThreadShell must free
    // javaThreadShell 方法包装了 entryFunction 真正的函数入口 
    result = androidCreateRawThreadEtc(AndroidRuntime::javaThreadShell, args,
        threadName, threadPriority, threadStackSize, threadId);
    return result;
}



/*static*/ int AndroidRuntime::javaThreadShell(void* args) {
    void* start = ((void**)args)[0];
    void* userData = ((void **)args)[1];
    char* name = (char*) ((void **)args)[2];        // we own this storage
    free(args);
    JNIEnv* env;
    int result;

    /* 让 Native 线程附加到 Java 虚拟机(JVM) */
    if (javaAttachThread(name, &env) != JNI_OK)
        return -1;

    /*调用真正的线程入口函数*/
    result = (*(android_thread_func_t)start)(userData);

    // 线程方法退出后,让 Native 线程附剥离 JVM ,避免不必要的 JVM 资源占用。
    javaDetachThread();
    free(name);

    return result;
}


static int javaAttachThread(const char* threadName, JNIEnv** pEnv)
{
    JavaVMAttachArgs args;
    JavaVM* vm;
    jint result;
    // 获取 Zygote 进程全局的 java 虚拟机对象 
    vm = AndroidRuntime::getJavaVM();
    assert(vm != NULL);

    args.version = JNI_VERSION_1_4;
    args.name = (char*) threadName;
    args.group = NULL;
    // 让 Native 线程附加到 Java 虚拟机(JVM),从而可以使用 JNI 调用 Java 方法。
    result = vm->AttachCurrentThread(pEnv, (void*) &args);
    if (result != JNI_OK)
        ALOGI("NOTE: attach of thread '%s' failed\n", threadName);

    return result;
}

所有一个由 Zygote 进程孵化的进程,在 native 代码如果使用 android::Thread 可以调用 java 方法的

cpp 复制代码
// entryFunction : 为  AndroidRuntime::javaThreadShell 启动后会调用 _threadLoop
// userData : 线程函数的的参数 ,传递的是 android::Thread this 指针 
// name : 为线程名字 ,默认为 android:unnamed_thread
// threadPriority : 线程优先级 
// threadStackSize : 线程栈空间大小,默认为 0 
// threadId : 线程 id ,默认为 nullptr 传递的是 android::Thread 成员变量 mThread 
int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
                               void *userData,
                               const char* threadName __android_unused,
                               int32_t threadPriority,
                               size_t threadStackSize,
                               android_thread_id_t *threadId)
{
    pthread_attr_t attr;
    // 初始化线程属性 
    pthread_attr_init(&attr); 
    //让新创建的线程以分离(detached)状态运行,即它会 自动释放资源,而不需要 pthread_join 来回收 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    // threadName 不为 NULL
    if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
       // 创建 thread_data_t 结构体 
        thread_data_t* t = new thread_data_t;
        // 各个成员变量赋值 
        t->priority = threadPriority;
        t->threadName = threadName ? strdup(threadName) : NULL;
        t->entryFunction = entryFunction;
        t->userData = userData;
        // entryFunction 赋值为 trampoline 函数 
        entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
        // userData 赋值为 t 
        userData = t;
    }

    // 若 threadStackSize 不为 0 ,就设置栈空间
    if (threadStackSize) {
        pthread_attr_setstacksize(&attr, threadStackSize);
    }

    errno = 0;
    pthread_t thread;
    // 创建 libutil_thread_data 结构体 
    libutil_thread_data* pthread_arg = new libutil_thread_data;
    pthread_arg->entry_func = entryFunction;
    pthread_arg->entry_func_arg = userData;
    // 创建线程
    int result = pthread_create(&thread, &attr,
                    libutil_thread_trampoline, pthread_arg);
    // 释放 attr
    pthread_attr_destroy(&attr);
    if (result != 0) {
        ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, %s)\n"
             "(android threadPriority=%d)",
            entryFunction, result, strerror(errno), threadPriority);
        return 0;
    }
    if (threadId != nullptr) {
        *threadId = (android_thread_id_t)thread; // XXX: this is not portable
    }
    return 1;
}


// pthread_create 入口函数 函数 
// arg 为 libutil_thread_data 结构体 
static void* _Nonnull libutil_thread_trampoline(void* _Nonnull arg) {
  libutil_thread_data *data_ptr = static_cast<libutil_thread_data*>(arg);
  // 调用 thread_data_t::trampoline 函数 参数为 thread_data_t 结构体 
  int result = data_ptr->entry_func(data_ptr->entry_func_arg);
  // 删除 libutil_thread_data 结构体对象
  delete data_ptr;
  return reinterpret_cast<void*>(static_cast<uintptr_t>(result));
}

 // 包装线程启动函数,在线程启动前会先运行 trampoline 函数 再执行真正的线程代码
 // 为啥要包装一下呢,这是为了给线程设置线程名,
 // 因为设置线程名是通过 prctl(PR_SET_NAME) 函数设置 ,该函数只有在运行的线程才有效 
 // 还有设置线程优先级,父线程也不知道子线程什么时候运行,设置时需要子线程ID,
 // 当有子线程ID时,子线程启动函数说不定已经运行了,所以在运行子线程函数之前先包装一下,
 // 设置好优先级和线程名字后在运行真正的启动函数 
static int trampoline(const thread_data_t* t) {
    // 取出 thread_data_t 结构体的值 
    thread_func_t f = t->entryFunction;
    void* u = t->userData;
    int prio = t->priority;
    char * name = t->threadName;
    // 回收 thread_data_t 结构体
    delete t;
    // 设置线程优先级 
    setpriority(PRIO_PROCESS, 0, prio);
    // 如果 name 不为 空 
    if (name) {
        // 设置线程名字
        androidSetThreadName(name);
        // 回收 name 字符串 
        free(name);
    }
    // 调用真正的入口函数 
    return f(u);
}

// 真正的入口函数 
int Thread::_threadLoop(void* user)
{
    // 传递的 user 为 android::Thread 对象 
    Thread* const self = static_cast<Thread*>(user);
    // 强引用 确保 Thread 在 _threadLoop() 运行时不会被外部意外销毁
    sp<Thread> strong(self->mHoldSelf);
    // 弱引用 
    wp<Thread> weak(strong);
    // 清除 mHoldSelf 对自身的引用,
    self->mHoldSelf.clear();
    // 获取线程 tid
    self->mTid = gettid();
    bool first = true;
    // do while 循环 
    do {
        bool result;
       
        if (first) {
            // 第一次执行 
            first = false;
            // 判断是否可以开始执行 默认为 OK 
            self->mStatus = self->readyToRun();
            result = (self->mStatus == OK);
            // 如果准备好执行了,并且没有调用退出 
            if (result && !self->exitPending()) {
                // 调用 android::Thread 虚函数 threadLoop() 
                result = self->threadLoop();
            }
        } else {
            result = self->threadLoop();
        }

        // establish a scope for mLock
        {
        Mutex::Autolock _l(self->mLock);
        // 如果没有准备好 ,或者 threadLoop 函数返回 false ,或者要求退出 
        if (result == false || self->mExitPending) {
            self->mExitPending = true;
            self->mRunning = false;
            self->mThread = thread_id_t(-1);
            // 通知等待退出的线程,已经退出了 
            self->mThreadExitedCondition.broadcast();
            // 跳出循环 ,线程退出 
            break;
        }
        }

        // 清除强引用,让线程有机会退出 
        strong.clear();
        // 尝试将弱引用提升为强引用,如果对象还未被销毁,就返回一个有效的 sp<T>,否则返回 nullptr。
        // 如果外部还有 android::Thread 对象的强引用,线程不会退出 
        strong = weak.promote();
    } while(strong != nullptr);  // android::Thread 对象强引用没有清除 ,一直循环

    return 0;
}
相关推荐
大胃粥1 小时前
Android V app 冷启动(8) 动画结束
android
ufo00l1 小时前
Kotlin在Android中有哪些重要的应用和知识点是需要学习或者重点关注的
android
AJi1 小时前
Android音视频框架探索(二):Binder——系统服务的通信基础
android·ffmpeg·音视频开发
tjsoft2 小时前
Nginx配置伪静态,URL重写
android·运维·nginx
努力学习的小廉2 小时前
【C++11(中)】—— 我与C++的不解之缘(三十一)
android·java·c++
tangweiguo030519873 小时前
打破界限:Android XML与Jetpack Compose深度互操作指南
android·kotlin·compose
Watink Cpper4 小时前
[MySQL初阶]MySQL(8)索引机制:下
android·数据库·b树·mysql·b+树·myisam·innodedb
一起搞IT吧4 小时前
高通camx IOVA内存不足,导致10-15x持续拍照后,点击拍照键定屏无反应,过一会相机闪退
android·数码相机
前行的小黑炭6 小时前
设计模式:为什么使用模板设计模式(不相同的步骤进行抽取,使用不同的子类实现)减少重复代码,让代码更好维护。
android·java·kotlin
ufo00l7 小时前
2025年了,Rxjava解决的用户痛点,是否kotlin协程也能解决,他们各有什么优缺点?
android