先来看一下线程头文件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,不会再被回调