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 M3U8视频播放器
android·音视频
q***57742 小时前
MySql的慢查询(慢日志)
android·mysql·adb
JavaNoober2 小时前
Android 前台服务 "Bad Notification" 崩溃机制分析文档
android
城东米粉儿3 小时前
关于ObjectAnimator
android
zhangphil4 小时前
Android渲染线程Render Thread的RenderNode与DisplayList,引用Bitmap及Open GL纹理上传GPU
android
火柴就是我5 小时前
从头写一个自己的app
android·前端·flutter
lichong9516 小时前
XLog debug 开启打印日志,release 关闭打印日志
android·java·前端
用户69371750013846 小时前
14.Kotlin 类:类的形态(一):抽象类 (Abstract Class)
android·后端·kotlin
火柴就是我6 小时前
NekoBoxForAndroid 编译libcore.aar
android
Kaede67 小时前
MySQL中如何使用命令行修改root密码
android·mysql·adb