This article mainly aims to test whether the threadloop thread executes cyclically.
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. Execute
We can see that the threadloop is printed every one second, so the threadloop is executed cyclically.
If the android SP is replaced by a pointer, that is, strongpointer, threadloop is printed only once. As follows:
// Sp <threadtest> thr = new threadtest ();
Threadtest * thr = new threadtest ();
Or return false in the threadloop function, and print the threadloop only once.
The reason is that the Thread class is being implemented,
The thread is created by pthreads or win32_threads, And the thread entry is set to _ threadloop.
_ Threadloop then calls the threadloop of the threadtest class and sets the threadloop
In the do-while loop, the loop is exited only when threadloop returns false or the thread object pointer is not implemented by SP.
_ Threadloop sample code:
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;}
For SP and WP, refer:
In-depth understanding of common android classes