现在的位置: 首页 > 综合 > 正文

Android native线程

2018年01月11日 ⁄ 综合 ⁄ 共 5705字 ⁄ 字号 评论关闭

先来看一下线程头文件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 := optional
LOCAL_SRC_FILES:= \
     main.cpp \
     threadtest.cpp

LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES

LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder

LOCAL_C_INCLUDES := \
    $(call include-path-for, corecg graphics)


LOCAL_MODULE:= threadtest


include $(BUILD_EXECUTABLE)

4)运行结果

root@android:/ # threadtest
12-11 20:44:29.212 D/ThreadTest( 5193): main loop 0
12-11 20:44:29.212 D/ThreadTest( 5193):
12-11 20:44:29.212 D/ThreadTest( 5193): ThreadTest readyToRun
12-11 20:44:29.212 D/ThreadTest( 5193): thread loop count :1
12-11 20:44:29.712 D/ThreadTest( 5193): thread loop count :2
12-11 20:44:30.212 D/ThreadTest( 5193): main loop 1
12-11 20:44:30.212 D/ThreadTest( 5193):
12-11 20:44:30.212 D/ThreadTest( 5193): thread loop count :3
12-11 20:44:30.712 D/ThreadTest( 5193): thread loop count :4
12-11 20:44:31.212 D/ThreadTest( 5193): main loop 2
12-11 20:44:31.212 D/ThreadTest( 5193):
12-11 20:44:31.212 D/ThreadTest( 5193): thread loop count :5
12-11 20:44:31.712 D/ThreadTest( 5193): thread loop count :6
12-11 20:44:32.212 D/ThreadTest( 5193): main loop 3
12-11 20:44:32.212 D/ThreadTest( 5193):
12-11 20:44:32.212 D/ThreadTest( 5193): thread loop count :7
12-11 20:44:32.712 D/ThreadTest( 5193): thread loop count :8
12-11 20:44:33.212 D/ThreadTest( 5193): main loop 4
12-11 20:44:33.212 D/ThreadTest( 5193):
12-11 20:44:33.212 D/ThreadTest( 5193): thread loop count :9
12-11 20:44:33.712 D/ThreadTest( 5193): thread loop count :10
12-11 20:44:34.212 D/ThreadTest( 5193): main loop 5
12-11 20:44:34.212 D/ThreadTest( 5193):
12-11 20:44:34.212 D/ThreadTest( 5193): thread loop count :11
12-11 20:44:34.712 D/ThreadTest( 5193): thread loop count :12
12-11 20:44:35.212 D/ThreadTest( 5193): main loop 6
12-11 20:44:35.212 D/ThreadTest( 5193):
12-11 20:44:35.212 D/ThreadTest( 5193): thread loop count :13
12-11 20:44:35.712 D/ThreadTest( 5193): thread loop count :14
12-11 20:44:36.212 D/ThreadTest( 5193): main loop 7
12-11 20:44:36.212 D/ThreadTest( 5193):
12-11 20:44:36.212 D/ThreadTest( 5193): thread loop count :15
12-11 20:44:36.712 D/ThreadTest( 5193): thread loop count :16
12-11 20:44:37.212 D/ThreadTest( 5193): main loop 8
12-11 20:44:37.212 D/ThreadTest( 5193):
12-11 20:44:37.212 D/ThreadTest( 5193): thread loop count :17
12-11 20:44:37.712 D/ThreadTest( 5193): thread loop count :18
12-11 20:44:38.212 D/ThreadTest( 5193): main loop 9
12-11 20:44:38.212 D/ThreadTest( 5193):
12-11 20:44:38.212 D/ThreadTest( 5193): thread loop count :19
12-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,不会再被回调


抱歉!评论已关闭.