本文主要是想測試 threadLoop 線程是不是迴圈執行。
1. ThreadTest.cpp
#include <binder/IPCThreadState.h>#include <binder/ProcessState.h>#include <utils/threads.h>namespace android { class ThreadTest : public Thread { virtual bool threadLoop(); }; bool ThreadTest::threadLoop() { printf("threadLoop\n"); sleep(1); return true; }}using namespace android;int main() { sp<ThreadTest> thr = new ThreadTest(); thr->run(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); return 0;}
2. Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS:= optionalLOCAL_SRC_FILES := \ ThreadTest.cppLOCAL_SHARED_LIBRARIES := \ libutils \ libbinderLOCAL_MODULE := ThreadTestinclude $(BUILD_EXECUTABLE)
3. 執行
可以看到每隔1秒,列印一次threadLoop,所以threadLoop是迴圈執行。
若用指標代替android的sp,即StrongPointer,則只列印一次threadLoop。如下所示:
//sp<ThreadTest> thr = new ThreadTest();
ThreadTest *thr = new ThreadTest();
或者在threadLoop函數中return false,也只列印一次threadLoop。
原因是Thread類的實現中,
先由pthreads或win32_threads實現建立thread,並將線程入口設為_threadLoop。
_threadLoop再調用thread類實現者(ThreadTest)的threadLoop,並將這個threadLoop
放在do-while迴圈中,只有當threadLoop返回false或線程對象指標不是sp實現時,會退出迴圈。
_threadLoop示意代碼:
int Thread::_threadLoop(void* user){ Thread* const self = static_cast<Thread*>(user); sp<Thread> strong(self->mHoldSelf); wp<Thread> weak(strong); self->mHoldSelf.clear();#ifdef HAVE_ANDROID_OS // this is very useful for debugging with gdb self->mTid = gettid();#endif bool first = true; do { bool result; if (first) { first = false; self->mStatus = self->readyToRun(); result = (self->mStatus == NO_ERROR); if (result && !self->exitPending()) { // Binder threads (and maybe others) rely on threadLoop // running at least once after a successful ::readyToRun() // (unless, of course, the thread has already been asked to exit // at that point). // This is because threads are essentially used like this: // (new ThreadSubclass())->run(); // The caller therefore does not retain a strong reference to // the thread and the thread would simply disappear after the // successful ::readyToRun() call instead of entering the // threadLoop at least once. result = self->threadLoop(); } } else { result = self->threadLoop(); } // establish a scope for mLock { Mutex::Autolock _l(self->mLock); if (result == false || self->mExitPending) { self->mExitPending = true; self->mRunning = false; // clear thread ID so that requestExitAndWait() does not exit if // called by a new thread using the same thread ID as this one. self->mThread = thread_id_t(-1); // note that interested observers blocked in requestExitAndWait are // awoken by broadcast, but blocked on mLock until break exits scope self->mThreadExitedCondition.broadcast(); break; } } // Release our strong reference, to let a chance to the thread // to die a peaceful death. strong.clear(); // And immediately, re-acquire a strong reference for the next loop strong = weak.promote(); } while(strong != 0); return 0;}
關於sp,wp,可參考:
深入理解android常用類