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