Android native线程

来源:互联网 发布:淘宝深度流量互踩 编辑:程序博客网 时间:2024/06/07 19:17

先来看一下线程头文件threads.h

class Thread : virtual public RefBase{public:    // Create a Thread object, but doesn't create or start the associated    // thread. See the run() method.                        Thread(bool canCallJava = true);    virtual             ~Thread();    // Start the thread in threadLoop() which needs to be implemented.    virtual status_t    run(    const char* name = 0,                                int32_t priority = PRIORITY_DEFAULT,                                size_t stack = 0);        // Ask this object's thread to exit. This function is asynchronous, when the    // function returns the thread might still be running. Of course, this    // function can be called from a different thread.    virtual void        requestExit();    // Good place to do one-time initializations    virtual status_t    readyToRun();        // Call requestExit() and wait until this object's thread exits.    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call    // this function from this object's thread. Will return WOULD_BLOCK in    // that case.            status_t    requestExitAndWait();    // Wait until this object's thread exits. Returns immediately if not yet running.    // Do not call from this object's thread; will return WOULD_BLOCK in that case.            status_t    join();protected:    // exitPending() returns true if requestExit() has been called.            bool        exitPending() const;    private:    // Derived class must implement threadLoop(). The thread starts its life    // here. There are two ways of using the Thread object:    // 1) loop: if threadLoop() returns true, it will be called again if    //          requestExit() wasn't called.    // 2) once: if threadLoop() returns false, the thread will exit upon return.    virtual bool        threadLoop() = 0;private:    Thread& operator=(const Thread&);    static  int             _threadLoop(void* user);    const   bool            mCanCallJava;    // always hold mLock when reading or writing            thread_id_t     mThread;    mutable Mutex           mLock;            Condition       mThreadExitedCondition;            status_t        mStatus;    // note that all accesses of mExitPending and mRunning need to hold mLock    volatile bool           mExitPending;    volatile bool           mRunning;            sp<Thread>      mHoldSelf;#if HAVE_ANDROID_OS            int             mTid;#endif};

我们来实现一个简单的demo:

1)threadtest.h

#ifndef THREAD_TEST_H#define THREAD_TEST_H#include <stdint.h>#include <sys/types.h>#include <utils/threads.h>namespace android {class ThreadTest : public Thread{private:    int loop_cnt;public:    ThreadTest();    ThreadTest(bool canCallJava);    virtual ~ThreadTest();    void onFirstRef();    virtual bool threadLoop();    status_t readyToRun();};}#endif // THREAD_TEST_H
2)threadtest.cpp

#include <utils/Log.h>#include "threadtest.h"#define LOG_TAG "ThreadTest"namespace android {    ThreadTest::ThreadTest() : Thread(false)    {        loop_cnt = 1;    }    ThreadTest::ThreadTest(bool canCallJava) : Thread(canCallJava)    {        loop_cnt = 1;    }    ThreadTest::~ThreadTest()    {    }    status_t ThreadTest::readyToRun()    {        LOGD("ThreadTest readyToRun\n");        return NO_ERROR;    }    void ThreadTest::onFirstRef()    {        run("ThreadTest", PRIORITY_NORMAL);    }    bool ThreadTest::threadLoop() {        LOGD("thread loop count :%d\n",loop_cnt);        loop_cnt++;        usleep(500000);        return true;    }}

3)main.cpp

#include <utils/Log.h>#include "threadtest.h"using namespace android;#define LOG_TAG "ThreadTest"int main(int argc, char *argv[]){    sp<ThreadTest>  mythread = new ThreadTest;    for( int i = 0 ; i < 10 ; i++ )    {        LOGD("main loop %d\n ",i);        sleep(1);    }    LOGD("Stop Thread\n");    mythread->requestExit();    mythread->join();    return 0;}

4)Android.mk

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES:= \     main.cpp \     threadtest.cppLOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPESLOCAL_SHARED_LIBRARIES := \    libcutils \    libutils \    libbinderLOCAL_C_INCLUDES := \    $(call include-path-for, corecg graphics)LOCAL_MODULE:= threadtestinclude $(BUILD_EXECUTABLE)

4)运行结果

root@android:/ # threadtest12-11 20:44:29.212 D/ThreadTest( 5193): main loop 012-11 20:44:29.212 D/ThreadTest( 5193):12-11 20:44:29.212 D/ThreadTest( 5193): ThreadTest readyToRun12-11 20:44:29.212 D/ThreadTest( 5193): thread loop count :112-11 20:44:29.712 D/ThreadTest( 5193): thread loop count :212-11 20:44:30.212 D/ThreadTest( 5193): main loop 112-11 20:44:30.212 D/ThreadTest( 5193):12-11 20:44:30.212 D/ThreadTest( 5193): thread loop count :312-11 20:44:30.712 D/ThreadTest( 5193): thread loop count :412-11 20:44:31.212 D/ThreadTest( 5193): main loop 212-11 20:44:31.212 D/ThreadTest( 5193):12-11 20:44:31.212 D/ThreadTest( 5193): thread loop count :512-11 20:44:31.712 D/ThreadTest( 5193): thread loop count :612-11 20:44:32.212 D/ThreadTest( 5193): main loop 312-11 20:44:32.212 D/ThreadTest( 5193):12-11 20:44:32.212 D/ThreadTest( 5193): thread loop count :712-11 20:44:32.712 D/ThreadTest( 5193): thread loop count :812-11 20:44:33.212 D/ThreadTest( 5193): main loop 412-11 20:44:33.212 D/ThreadTest( 5193):12-11 20:44:33.212 D/ThreadTest( 5193): thread loop count :912-11 20:44:33.712 D/ThreadTest( 5193): thread loop count :1012-11 20:44:34.212 D/ThreadTest( 5193): main loop 512-11 20:44:34.212 D/ThreadTest( 5193):12-11 20:44:34.212 D/ThreadTest( 5193): thread loop count :1112-11 20:44:34.712 D/ThreadTest( 5193): thread loop count :1212-11 20:44:35.212 D/ThreadTest( 5193): main loop 612-11 20:44:35.212 D/ThreadTest( 5193):12-11 20:44:35.212 D/ThreadTest( 5193): thread loop count :1312-11 20:44:35.712 D/ThreadTest( 5193): thread loop count :1412-11 20:44:36.212 D/ThreadTest( 5193): main loop 712-11 20:44:36.212 D/ThreadTest( 5193):12-11 20:44:36.212 D/ThreadTest( 5193): thread loop count :1512-11 20:44:36.712 D/ThreadTest( 5193): thread loop count :1612-11 20:44:37.212 D/ThreadTest( 5193): main loop 812-11 20:44:37.212 D/ThreadTest( 5193):12-11 20:44:37.212 D/ThreadTest( 5193): thread loop count :1712-11 20:44:37.712 D/ThreadTest( 5193): thread loop count :1812-11 20:44:38.212 D/ThreadTest( 5193): main loop 912-11 20:44:38.212 D/ThreadTest( 5193):12-11 20:44:38.212 D/ThreadTest( 5193): thread loop count :1912-11 20:44:38.712 D/ThreadTest( 5193): thread loop count :20

5)总结

ThreadTest类继承了Thread类也就间接的继承了RefBase类。

所以ThreadTest的对象第一次被智能指针(wp)引用的时候,对象的onFirstRef会被调用。

我们在onFirstRef里面调用线程的run()方法,线程类的run就会调用到线程方法_threadloop()方法(注意_threadloop前面的下划线).

而在_threadloop方法在调用我们定义的threadloop()方法前,会先调用我们重新的readyToRun()方法,以便我们进行一些初始化的操作。

然后调用threadloop();


1)主线程继承Thread类

2)readyToRun完成线程初始化工作

3)线程类集成onFirstRef()方法,可以在onFirstRef()中调用run()

4)重载主线程的threadloop()方法;

   threadloop()方法返回true,会一直被回调;

    threadloop()方法返回false,不会再被回调


0 0
原创粉丝点击