分享

Android Framework中的线程Thread及它的threadLoop方法

 Elaine个人小馆 2016-08-17

当初跟踪Camera的代码中的时候一直追到了HAL层,而在Framework中的代码看见了许许多多的Thread。它们普遍的特点就是有一个threadLoop方法。按照字面的意思应该是这个线程能够循环处理数据。对应我想到到了java上层中的HandlerThread,这个估计也差不多,但当时心里总有一个疙瘩,想弄清楚它为什么能够循环,还有它到底是怎么循环起来的?

Android中java世界的Thread

我们先来看看java是怎么创建一个线程的。这个是最舒服的,也是我最熟悉的。

new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub ... }}).start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

当然,你也可以在android中创建一个消息循环的HandlerThread

HandlerThread mThread = new HandlerThread('test');mThread.start();Handler mHandler = new Handler(mThread.getLooper()){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); }};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

上面中通过mHandler发送消息就可以在mThread中处理了,并且这个mThread不是UIThread,不会阻塞主线程。
HandlerThread是一个好东西,在源码中处处可见,希望对此不熟悉的新手及时去学习下它的用法。

Linux下c语言的Thread

java世界的Thread很方便,那么c呢?
Android基于linux所以,多线程编程也应该基于linux下的多线程。linux下的c语言用pthread。大家可以看这篇文章。
linux下C/C++,多线程pthread

我把里面的例子改良了一下
test.c

#include #include #include #include //线程函数void *test(void *ptr){ int i; for(i=0;i<8;i++) { printf('the pthread running ,count: %d\n',i); sleep(1); }}int main(void){ pthread_t pId; int i,ret; //创建子线程,线程id为pId ret = pthread_create(&pId,NULL,test,NULL); if(ret != 0) { printf('create pthread error!\n'); exit(1); } for(i=0;i < 5;i++) { printf('main thread running ,count : %d\n',i); sleep(1); } printf('main thread will exit when pthread is over\n'); //等待线程pId的完成 pthread_join(pId,NULL); printf('main thread exit\n'); return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

然后编译

gcc -o test test.c -lpthread./test
  • 1
  • 2

运行结果如下

main thread running ,count : 0the pthread running ,count: 0main thread running ,count : 1the pthread running ,count: 1main thread running ,count : 2the pthread running ,count: 2main thread running ,count : 3the pthread running ,count: 3main thread running ,count : 4the pthread running ,count: 4main thread will exit when pthread is overthe pthread running ,count: 5the pthread running ,count: 6the pthread running ,count: 7main thread exit
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

例子比较简单,主要是创建一个线程,然后主线程等待子线程运行完毕再退出。

Android Framework中的Thread

下面焦点回到文章的主题当中,我们来看看Framework中常用的Thread是个何种形态。
先看看活生生的例子。
在源码中搜索threadLoop,当然也可以搜索thread,然后随便挑选一个Thread子类进行研究。这里挑选
/frameworks/av/services/audioflinger/AudioWatchdog.h

#ifndef AUDIO_WATCHDOG_H#define AUDIO_WATCHDOG_H#include #include namespace android {......class AudioWatchdog : public Thread {public: AudioWatchdog(unsigned periodMs = 50) : Thread(false /*canCallJava*/), mPaused(false), mPeriodNs(periodMs * 1000000), mMaxCycleNs(mPeriodNs * 2), // mOldTs // mLogTs initialized below mOldTsValid(false), mUnderruns(0), mLogs(0), mDump(&mDummyDump) {#define MIN_TIME_BETWEEN_LOGS_SEC 60 // force an immediate log on first underrun mLogTs.tv_sec = MIN_TIME_BETWEEN_LOGS_SEC; mLogTs.tv_nsec = 0; } virtual ~AudioWatchdog() { } // Do not call Thread::requestExitAndWait() without first calling requestExit(). // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough. virtual void requestExit(); // FIXME merge API and implementation with AudioTrackThread void pause(); // suspend thread from execution at next loop boundary void resume(); // allow thread to execute, if not requested to exit // Where to store the dump, or NULL to not update void setDump(AudioWatchdogDump* dump);private: virtual bool threadLoop(); Mutex mMyLock; // Thread::mLock is private Condition mMyCond; // Thread::mThreadExitedCondition is private bool mPaused; // whether thread is currently paused ......};} // namespace android#endif // AUDIO_WATCHDOG_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

我们可以看到AudioWatchDog确实是Thread的子类,那好,下面看实现。
/frameworks/av/services/audioflinger/AudioWatchdog.cpp

#define LOG_TAG 'AudioWatchdog'//#define LOG_NDEBUG 0#include <utils/Log.h>#include 'AudioWatchdog.h'namespace android {bool AudioWatchdog::threadLoop(){ { AutoMutex _l(mMyLock); if (mPaused) { mMyCond.wait(mMyLock); // ignore previous timestamp after resume() mOldTsValid = false; // force an immediate log on first underrun after resume() mLogTs.tv_sec = MIN_TIME_BETWEEN_LOGS_SEC; mLogTs.tv_nsec = 0; // caller will check for exitPending() return true; } } struct timespec newTs; int rc = clock_gettime(CLOCK_MONOTONIC, &newTs); if (rc != 0) { pause(); return false; } if (!mOldTsValid) { mOldTs = newTs; mOldTsValid = true; return true; } time_t sec = newTs.tv_sec - mOldTs.tv_sec; long nsec = newTs.tv_nsec - mOldTs.tv_nsec; if (nsec < 0) { --sec; nsec += 1000000000; } mOldTs = newTs; // cycleNs is same as sec*1e9 + nsec, but limited to about 4 seconds uint32_t cycleNs = nsec; if (sec > 0) { if (sec < 4) { cycleNs += sec * 1000000000; } else { cycleNs = 4000000000u; } } mLogTs.tv_sec += sec; if ((mLogTs.tv_nsec += nsec) >= 1000000000) { mLogTs.tv_sec++; mLogTs.tv_nsec -= 1000000000; } if (cycleNs > mMaxCycleNs) { mDump->mUnderruns = ++mUnderruns; if (mLogTs.tv_sec >= MIN_TIME_BETWEEN_LOGS_SEC) { mDump->mLogs = ++mLogs; mDump->mMostRecent = time(NULL); ALOGW('Insufficient CPU for load: expected=%.1f actual=%.1f ms; underruns=%u logs=%u', mPeriodNs * 1e-6, cycleNs * 1e-6, mUnderruns, mLogs); mLogTs.tv_sec = 0; mLogTs.tv_nsec = 0; } } struct timespec req; req.tv_sec = 0; req.tv_nsec = mPeriodNs; rc = nanosleep(&req, NULL); if (!((rc == 0) || (rc == -1 && errno == EINTR))) { pause(); return false; } return true;}void AudioWatchdog::requestExit(){ // must be in this order to avoid a race condition Thread::requestExit(); resume();}void AudioWatchdog::pause(){ AutoMutex _l(mMyLock); mPaused = true;}void AudioWatchdog::resume(){ AutoMutex _l(mMyLock); if (mPaused) { mPaused = false; mMyCond.signal(); }}} // namespace android
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101

很明显,它的核心方法就是threadLoop(),在本文中我们不关心它具体的功能,只想确定它是怎么启动的呢?又是怎么循环运行的呢?带着疑问我又在源码中搜索关键字AudioWatchdog
结果发现有两个地方引用了。

/frameworks/av/services/audioflinger/AudioFlinger.h/frameworks/av/services/audioflinger/AudioFlinger.cpp
  • 1
  • 2

在AudioFlinger.h中MixerThread中有个AudioWatchdog的sp对象

class MixerThread : public PlaybackThread { public: MixerThread (const sp& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, type_t type = MIXER); virtual ~MixerThread(); protected: AudioMixer* mAudioMixer; // normal mixer private: sp mAudioWatchdog; // non-0 if there is an audio watchdog thread };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

我们再看代码
/frameworks/av/services/audioflinger/AudioFlinger.cpp

AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, type_t type) : PlaybackThread(audioFlinger, output, id, device, type), // mAudioMixer below // mFastMixer below mFastMixerFutex(0) // mOutputSink below // mPipeSink below // mNormalSink below{......#ifdef AUDIO_WATCHDOG // create and start the watchdog mAudioWatchdog = new AudioWatchdog(); mAudioWatchdog->setDump(&mAudioWatchdogDump); //AudioWatchdog的run方法在此调用,所以线程启动 mAudioWatchdog->run('AudioWatchdog', PRIORITY_URGENT_AUDIO); tid = mAudioWatchdog->getTid(); err = requestPriority(getpid_cached, tid, kPriorityFastMixer); if (err != 0) { ALOGW('Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d', kPriorityFastMixer, getpid_cached, tid, err); }#endif......}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

删掉不相关代码,我们看到AudioWatchdog对象确实创建了,并且调用了它的run方法。在java中Thread的run方法就是启动,这个也应该如此。但是如之前的源码所示AudioWatchdog.cpp中并没有实现run方法,怎么办呢?别紧张,它还有父类Thread.

/frameworks/native/include/utils/Thread.h

#ifndef _LIBS_UTILS_THREAD_H#define _LIBS_UTILS_THREAD_H#include #include #include #if defined(HAVE_PTHREADS)# include #endif#include #include #include #include #include #include // ---------------------------------------------------------------------------namespace android {// ---------------------------------------------------------------------------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();#ifdef HAVE_ANDROID_OS // Return the thread's kernel ID, same as the thread itself calling gettid() or // androidGetTid(), or -1 if the thread is not running. pid_t getTid() const;#endifprotected: // 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 mHoldSelf;#ifdef HAVE_ANDROID_OS // legacy for debugging, not used by getTid() as it is set by the child thread // and so is not initialized until the child reaches that point pid_t mTid;#endif};}; // namespace android// ---------------------------------------------------------------------------#endif // _LIBS_UTILS_THREAD_H//
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

可以看到确实有run方法。那下面看看它的实现

status_t Thread::run(const char* name, int32_t priority, size_t stack){ Mutex::Autolock _l(mLock); if (mRunning) { // thread already started return INVALID_OPERATION; } // reset status and exitPending to their default value, so we can // try again after an error happened (either below, or in readyToRun()) mStatus = NO_ERROR; mExitPending = false; mThread = thread_id_t(-1); // hold a strong reference on ourself mHoldSelf = this; mRunning = true; bool res; if (mCanCallJava) { res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread); } else { res = androidCreateRawThreadEtc(_threadLoop, this, name, priority, stack, &mThread); } if (res == false) { mStatus = UNKNOWN_ERROR; // something happened! mRunning = false; mThread = thread_id_t(-1); mHoldSelf.clear(); // 'this' may have gone away after this. return UNKNOWN_ERROR; } // Do not refer to mStatus here: The thread is already running (may, in fact // already have exited with a valid mStatus result). The NO_ERROR indication // here merely indicates successfully starting the thread and does not // imply successful termination/execution. return NO_ERROR; // Exiting scope of mLock is a memory barrier and allows new thread to run}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

run()方法中有这么一段

if (mCanCallJava) { res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread); } else { res = androidCreateRawThreadEtc(_threadLoop, this, name, priority, stack, &mThread); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

mCanCallJava的意思是能不能被JNI层调用,然后根据值去创建Thread,这里有两个分支,我们就选择createThreadEtc()
最终代码会走到这里

int androidCreateRawThreadEtc(android_thread_func_t entryFunction, void *userData, const char* threadName, int32_t threadPriority, size_t threadStackSize, android_thread_id_t *threadId){ ...... entryFunction = (android_thread_func_t)&thread_data_t::trampoline; userData = t; }#endif if (threadStackSize) { pthread_attr_setstacksize(&attr, threadStackSize); } errno = 0; pthread_t thread; //在此创建,文章开头我有写例子怎么用c语言创建一个线程 int result = pthread_create(&thread, &attr, (android_pthread_entry)entryFunction, userData); pthread_attr_destroy(&attr); if (result != 0) { ALOGE('androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n' '(android threadPriority=%d)', entryFunction, result, errno, threadPriority); return 0; } ...... return 1;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

删除了不相关代码,大家看看是不是很熟悉啊。我在文章开始的部分就写出了linux下c语言pthread创建线程的例子,大家可以回头看看。也就是pthread_create()。这里面传进来的entryFunction是Thread中的_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. //调用threadLoop() 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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

_threadLoop()这个方法就是Thread的最大秘密,它是一个while循环。

1、创建线程时,会sp和wp一次线程本身。
2、如果是第一次执行会运行线程的readyToRun()方法,再执行threadLoop(),否则,直接运行threadLoop()。
3、threadLoop()方法有返回值,如果threadLoop()返回false的时候,线程会做清理工作,然后退出while循环,结束运行。

所以在这里,我开始时的疑问—为什么线程Thread中的threadLoop()能够循环处理数据就到此做了说明。
Thread被创建,
Thread中的run被调用,
__threadLoop()被调用,
readyToRun()被调用,
然后循环调用threadLoop()。
并且在threadLoop()返回false时,可以退出循环。

!!!
!!!
还有,最关键的一点是threadLoop能够循环其实是因为调用它的_threadLoop()方法里面有一个while循环

特殊情况

有的时候Android Framework中Thread的run()方法很难发现在哪里被调用。如SurfaceFlinger它也是一个Thread子类。在源码中搜索可以发现它的创建位置

class SurfaceFlinger : public BinderService, public BnSurfaceComposer, private IBinder::DeathRecipient, private Thread, private HWComposer::EventHandler{public: static char const* getServiceName() { return 'SurfaceFlinger'; } SurfaceFlinger(); /* ------------------------------------------------------------------------ * Thread interface */ virtual bool threadLoop(); virtual status_t readyToRun(); virtual void onFirstRef();};// ---------------------------------------------------------------------------}; // namespace android#endif // ANDROID_SURFACE_FLINGER_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

去找它创建的地方
/frameworks/base/cmds/system_server/library/system_init.cpp

extern 'C' status_t system_init(){ ALOGI('Entered system_init()'); sp proc(ProcessState::self()); sp sm = defaultServiceManager(); ALOGI('ServiceManager: %p\n', sm.get()); char propBuf[PROPERTY_VALUE_MAX]; property_get('system_init.startsurfaceflinger', propBuf, '1'); if (strcmp(propBuf, '1') == 0) { // Start the SurfaceFlinger SurfaceFlinger::instantiate(); } // And now start the Android runtime. We have to do this bit // of nastiness because the Android runtime initialization requires // some of the core system services to already be started. // All other servers should just start the Android runtime at // the beginning of their processes's main(), before calling // the init function. ALOGI('System server: starting Android runtime.\n'); AndroidRuntime* runtime = AndroidRuntime::getRuntime(); ALOGI('System server: starting Android services.\n'); JNIEnv* env = runtime->getJNIEnv(); if (env == NULL) { return UNKNOWN_ERROR; } jclass clazz = env->FindClass('com/android/server/SystemServer'); if (clazz == NULL) { return UNKNOWN_ERROR; } jmethodID methodId = env->GetStaticMethodID(clazz, 'init2', '()V'); if (methodId == NULL) { return UNKNOWN_ERROR; } env->CallStaticVoidMethod(clazz, methodId); ALOGI('System server: entering thread pool.\n'); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); ALOGI('System server: exiting thread pool.\n'); return NO_ERROR;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

我们可以看到

SurfaceFlinger::instantiate();
  • 1

但它本身并没有实现instantiate()方法,那之类找它的父类了。
/frameworks/native/include/binder/BinderService.h

namespace android {templateclass BinderService{public: static status_t publish(bool allowIsolated = false) { sp sm(defaultServiceManager()); return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); } static void publishAndJoinThreadPool(bool allowIsolated = false) { sp sm(defaultServiceManager()); sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); } static void instantiate() { publish(); } static status_t shutdown() { return NO_ERROR; }};}; // namespace android// ---------------------------------------------------------------------------#endif // ANDROID_BINDER_SERVICE_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

会调用publish()方法。
而SERVICE在这里是一个模板类。在这里SERVICE自然对应SurfaceFlinger
所以publish()会向ServiceManager添加一个Service这个Service就是Surfaceflinger。

然后我们看SurfaceFlinger的构造函数
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

SurfaceFlinger::SurfaceFlinger() : BnSurfaceComposer(), Thread(false), mTransactionFlags(0), mTransactionPending(false), mAnimTransactionPending(false), mLayersRemoved(false), mRepaintEverything(0), mBootTime(systemTime()), mVisibleRegionsDirty(false), mHwWorkListDirty(false), mDebugRegion(0), mDebugDDMS(0), mDebugDisableHWC(0), mDebugDisableTransformHint(0), mDebugInSwapBuffers(0), mLastSwapBufferTime(0), mDebugInTransaction(0), mLastTransactionTime(0), mBootFinished(false){ ALOGI('SurfaceFlinger is starting'); // debugging stuff... char value[PROPERTY_VALUE_MAX]; property_get('debug.sf.showupdates', value, '0'); mDebugRegion = atoi(value); property_get('debug.sf.ddms', value, '0'); mDebugDDMS = atoi(value); if (mDebugDDMS) { if (!startDdmConnection()) { // start failed, and DDMS debugging not enabled mDebugDDMS = 0; } } ALOGI_IF(mDebugRegion, 'showupdates enabled'); ALOGI_IF(mDebugDDMS, 'DDMS debugging enabled');}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

但是遗憾的是没有发现run()方法的影踪,没有办法只得去父类构造方法看
结果发现也没有!!!

没有办法,继续在源码中搜索SurfaceFlinger,结果发现与之相关的信息大多是sp
就看看sp吧。
sp是Android在c++中搞得类似java中弱引用、强引用的一套指针概念,那应该是方便回收吧。
而Android Framework中的c++世界,RefBase这个类有点像java中的Object.
而sp是一个模板类。这部分内容,请看点击下面链接

Android中的sp和wp指针

上面的链接讲得还算详细。这里纠结sp的过多细节,长话短说,总之第一次对SurfaceFlinger引用调用sp时会调用SurfaceFlinger的onFirstRef()方法。
那好,看代码吧

void SurfaceFlinger::onFirstRef(){ mEventQueue.init(this); //run方法在此被调用 run('SurfaceFlinger', PRIORITY_URGENT_DISPLAY); // Wait for the main thread to be done with its initialization mReadyToRunBarrier.wait();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

看见没有?run()方法在这里调用了。

所以,在Framework中如果你找不到一个Thread在何处被启动,那么去它的onFirstRef()方法中去看看吧

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多