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

Android中java世界的Thread

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


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

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

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

上面中通过mHandler发送消息就能够在mThread中处理了。而且这个mThread不是UIThread,不会堵塞主线程。

HandlerThread是一个好东西,在源代码中处处可见,希望对此不熟悉的新手及时去学习下它的使用方法。

Linux下c语言的Thread

java世界的Thread非常方便,那么c呢?

Android基于linux所以,多线程编程也应该基于linux下的多线程。linux下的c语言用pthread。大家能够看这篇文章。

linux下C/C++,多线程pthread

我把里面的样例改良了一下

test.c

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

然后编译

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

执行结果例如以下

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

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

Android Framework中的Thread

以下焦点回到文章的主题其中,我们来看看Framework中经常使用的Thread是个何种形态。

先看看活生生的样例。

在源代码中搜索threadLoop,当然也能够搜索thread,然后随便挑选一个Thread子类进行研究。

这里挑选

/frameworks/av/services/audioflinger/AudioWatchdog.h

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

我们能够看到AudioWatchDog确实是Thread的子类,那好。以下看实现。

/frameworks/av/services/audioflinger/AudioWatchdog.cpp

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

非常明显,它的核心方法就是threadLoop(),在本文中我们不关心它具体的功能。仅仅想确定它是怎么启动的呢?又是怎么循环执行的呢?带着疑问我又在源代码中搜索关键字AudioWatchdog

结果发现有两个地方引用了。

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

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


  1. class MixerThread : public PlaybackThread {
  2. public:
  3. MixerThread (const sp<AudioFlinger>& audioFlinger,
  4. AudioStreamOut* output,
  5. audio_io_handle_t id,
  6. audio_devices_t device,
  7. type_t type = MIXER);
  8. virtual ~MixerThread();
  9. protected:
  10. AudioMixer* mAudioMixer; // normal mixer
  11. private:
  12. sp<AudioWatchdog> mAudioWatchdog; // non-0 if there is an audio watchdog thread
  13. };

我们再看代码

/frameworks/av/services/audioflinger/AudioFlinger.cpp

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

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

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


  1. #ifndef _LIBS_UTILS_THREAD_H
  2. #define _LIBS_UTILS_THREAD_H
  3. #include <stdint.h>
  4. #include <sys/types.h>
  5. #include <time.h>
  6. #if defined(HAVE_PTHREADS)
  7. # include <pthread.h>
  8. #endif
  9. #include <utils/Condition.h>
  10. #include <utils/Errors.h>
  11. #include <utils/Mutex.h>
  12. #include <utils/RefBase.h>
  13. #include <utils/Timers.h>
  14. #include <utils/ThreadDefs.h>
  15. // ---------------------------------------------------------------------------
  16. namespace android {
  17. // ---------------------------------------------------------------------------
  18. class Thread : virtual public RefBase
  19. {
  20. public:
  21. // Create a Thread object, but doesn't create or start the associated
  22. // thread. See the run() method.
  23. Thread(bool canCallJava = true);
  24. virtual ~Thread();
  25. // Start the thread in threadLoop() which needs to be implemented.
  26. virtual status_t run( const char* name = 0,
  27. int32_t priority = PRIORITY_DEFAULT,
  28. size_t stack = 0);
  29. // Ask this object's thread to exit. This function is asynchronous, when the
  30. // function returns the thread might still be running. Of course, this
  31. // function can be called from a different thread.
  32. virtual void requestExit();
  33. // Good place to do one-time initializations
  34. virtual status_t readyToRun();
  35. // Call requestExit() and wait until this object's thread exits.
  36. // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
  37. // this function from this object's thread. Will return WOULD_BLOCK in
  38. // that case.
  39. status_t requestExitAndWait();
  40. // Wait until this object's thread exits. Returns immediately if not yet running.
  41. // Do not call from this object's thread; will return WOULD_BLOCK in that case.
  42. status_t join();
  43. #ifdef HAVE_ANDROID_OS
  44. // Return the thread's kernel ID, same as the thread itself calling gettid() or
  45. // androidGetTid(), or -1 if the thread is not running.
  46. pid_t getTid() const;
  47. #endif
  48. protected:
  49. // exitPending() returns true if requestExit() has been called.
  50. bool exitPending() const;
  51. private:
  52. // Derived class must implement threadLoop(). The thread starts its life
  53. // here. There are two ways of using the Thread object:
  54. // 1) loop: if threadLoop() returns true, it will be called again if
  55. // requestExit() wasn't called.
  56. // 2) once: if threadLoop() returns false, the thread will exit upon return.
  57. virtual bool threadLoop() = 0;
  58. private:
  59. Thread& operator=(const Thread&);
  60. static int _threadLoop(void* user);
  61. const bool mCanCallJava;
  62. // always hold mLock when reading or writing
  63. thread_id_t mThread;
  64. mutable Mutex mLock;
  65. Condition mThreadExitedCondition;
  66. status_t mStatus;
  67. // note that all accesses of mExitPending and mRunning need to hold mLock
  68. volatile bool mExitPending;
  69. volatile bool mRunning;
  70. sp<Thread> mHoldSelf;
  71. #ifdef HAVE_ANDROID_OS
  72. // legacy for debugging, not used by getTid() as it is set by the child thread
  73. // and so is not initialized until the child reaches that point
  74. pid_t mTid;
  75. #endif
  76. };
  77. }; // namespace android
  78. // ---------------------------------------------------------------------------
  79. #endif // _LIBS_UTILS_THREAD_H
  80. //

能够看到确实有run方法。那以下看看它的实现

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

run()方法中有这么一段

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

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

终于代码会走到这里

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

删除了不相关代码,大家看看是不是非常熟悉啊。我在文章開始的部分就写出了linux下c语言pthread创建线程的样例,大家能够回头看看。也就是pthread_create()

这里面传进来的entryFunction是Thread中的_threadLoop()

  1. int Thread::_threadLoop(void* user)
  2. {
  3. Thread* const self = static_cast<Thread*>(user);
  4. sp<Thread> strong(self->mHoldSelf);
  5. wp<Thread> weak(strong);
  6. self->mHoldSelf.clear();
  7. #ifdef HAVE_ANDROID_OS
  8. // this is very useful for debugging with gdb
  9. self->mTid = gettid();
  10. #endif
  11. bool first = true;
  12. do {
  13. bool result;
  14. if (first) {
  15. first = false;
  16. self->mStatus = self->readyToRun();
  17. result = (self->mStatus == NO_ERROR);
  18. if (result && !self->exitPending()) {
  19. // Binder threads (and maybe others) rely on threadLoop
  20. // running at least once after a successful ::readyToRun()
  21. // (unless, of course, the thread has already been asked to exit
  22. // at that point).
  23. // This is because threads are essentially used like this:
  24. // (new ThreadSubclass())->run();
  25. // The caller therefore does not retain a strong reference to
  26. // the thread and the thread would simply disappear after the
  27. // successful ::readyToRun() call instead of entering the
  28. // threadLoop at least once.
  29. //调用threadLoop()
  30. result = self->threadLoop();
  31. }
  32. } else {
  33. result = self->threadLoop();
  34. }
  35. // establish a scope for mLock
  36. {
  37. Mutex::Autolock _l(self->mLock);
  38. if (result == false || self->mExitPending) {
  39. self->mExitPending = true;
  40. self->mRunning = false;
  41. // clear thread ID so that requestExitAndWait() does not exit if
  42. // called by a new thread using the same thread ID as this one.
  43. self->mThread = thread_id_t(-1);
  44. // note that interested observers blocked in requestExitAndWait are
  45. // awoken by broadcast, but blocked on mLock until break exits scope
  46. self->mThreadExitedCondition.broadcast();
  47. break;
  48. }
  49. }
  50. // Release our strong reference, to let a chance to the thread
  51. // to die a peaceful death.
  52. strong.clear();
  53. // And immediately, re-acquire a strong reference for the next loop
  54. strong = weak.promote();
  55. } while(strong != 0);
  56. return 0;
  57. }

_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子类。

在源代码中搜索能够发现它的创建位置

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

去找它创建的地方

/frameworks/base/cmds/system_server/library/system_init.cpp

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

我们能够看到

  1. SurfaceFlinger::instantiate();

但它本身并没有实现instantiate()方法,那之类找它的父类了。

/frameworks/native/include/binder/BinderService.h

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

会调用publish()方法。

而SERVICE在这里是一个模板类。在这里SERVICE自然相应SurfaceFlinger

所以publish()会向ServiceManager加入一个Service这个Service就是Surfaceflinger。

然后我们看SurfaceFlinger的构造函数

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

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

可是遗憾的是没有发现run()方法的影踪,没有办法仅仅得去父类构造方法看

结果发现也没有!

。。

没有办法,继续在源代码中搜索SurfaceFlinger。结果发现与之相关的信息大多是sp<SurfaceFlinger>

就看看sp吧。

sp是Android在c++中搞得相似java中弱引用、强引用的一套指针概念,那应该是方便回收吧。

而Android Framework中的c++世界,RefBase这个类有点像java中的Object.

而sp是一个模板类。

这部分内容。请看点击以下链接

Android中的sp和wp指针

上面的链接讲得还算具体。这里纠结sp的过多细节。长话短说。总之第一次对SurfaceFlinger引用调用sp<SurfaceFlinger>时会调用SurfaceFlinger的onFirstRef()方法。

那好。看代码吧

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

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

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

Android Framework中的线程Thread及它的threadLoop方法的更多相关文章

  1. Java中的线程Thread方法之---interrupt()

    前几篇都介绍了Thread中的几个方法,相信大家都发现一个相似点,那就是sleep,join,wait这样的阻塞方法都必须捕获一个InterruptedException异常,顾名思义就是一个线程中断 ...

  2. Android开发中,那些让您觉得相见恨晚的方法、类或接口

    Android开发中,那些让你觉得相见恨晚的方法.类或接口本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常 ...

  3. Android Framework中Thread类

    Thread类是Android为线程操作而做的一个封装.代码在Thread.cpp中,其中还封装了一些与线程同步相关的类. Thread类 Thread类的构造函数中的有一个canCallJava T ...

  4. Android 线程Thread的2种实现方法

    在讲解之前有以下三点要说明: 1.在Android中有两种实现线程Thread的方法: ①扩展java.long.Thread类: ②实现Runnable()接口: 2.Thread类是线程类,它有两 ...

  5. 【转】android ddms中查看线程释疑

    原文网址:http://www.mobiletrain.org/lecture/doc/android/2011-05/457.html 大家都用过ddm,如果你用ddms查看一个程序的所有线程,你会 ...

  6. Java中的线程Thread总结

    首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Threa ...

  7. Android Framework中的Application Framework层介绍

    Android的四层架构相比大家都很清楚,老生常谈的说一下分别为:Linux2.6内核层,核心库层,应用框架层,应用层.我今天重点介绍一下应用框架层Framework,其实也是我自己的学习心得. Fr ...

  8. Java中的线程Thread方法之---suspend()和resume()

    前篇说到了Thread中的join方法,这一篇我们就来介绍一下suspend()和resume()方法,从字面意义上可以了解到这两个方法是一对的,suspend()方法就是将一个线程挂起(暂停),re ...

  9. Android开发中,那些让你觉得相见恨晚的方法、类或接口

    Throwable类中的getStackTrace()方法,根据这个方法可以得到函数的逐层调用地址,其返回值为StackTraceElement[],而在StackTraceElement类中有四个方 ...

随机推荐

  1. JavaScript 上下文环境和作用域,以及 call、apply 和 bind【转载+翻译+整理】

    --看到这篇文章,翻译国外的,虽说写得有点矫情,但总体来看,还是相当不错的- 本文内容 我在哪儿?你又是谁 ? this? 用 apply 和 call 掌控上下文环境 bind 之美 本文将说明上下 ...

  2. Timer 与 TimerTask 示例

    , 1000);// 1秒后执行 然后每隔1秒 执行一次 ); ); timer.cancel();//停止任务(程序停止) } } /** * 启动刷新滚动数据的定时器 */public void ...

  3. javascript高级语法学习

    可维护的代码意味着: 可读的 一致的 可预测的 看上去就像是同一个人写的 已记录 命名函数表达式 (function fn(){}) 他是表达式的原因是因为括号 ()是一个分组操作符,它的内部只能包含 ...

  4. 论asp.net out、ref、return

    论asp.net out.ref.return ref(引用类型) ref引用类型进出都必须赋值,赋值后会改变类型原来的指针. out(值类型) out值类型进可以不赋值,出必须赋值. return( ...

  5. 【Linux】Ubuntu配置服务自启动 sysv-rc-conf

    在Ubuntu下,配置服务系统开机自启动,使用的不是chkconfig,而是sysv-rc-conf. 且看如下: 安装: sudo apt-get install sysv-rc-conf 帮助信息 ...

  6. tar 使用总结

    今天需要备份数据,使用tar命令,总结一下. 压缩命令: tar -zvvf ticket-data-intgration.tar.gz ticket-data-intgration 压缩但是不包含某 ...

  7. ubuntu 下 cajview 替代方案

    .caj 是知网提供的论文的标准格式,但是,知网只提供 win 版的工具.这里尝试了两个两个方案,均可行,做一下记录在此. 1. 使用 wine 版的 cajview  pdf 可以正常用,但是 ca ...

  8. 在xpage上怎么用jdbc去连接sql server呀

    你去http://www.openntf.org/Internal/home.nsf 下載以下對應版本最新控件 XPages Extension Library 這裏面已經包括OSGI功能 OSGI在 ...

  9. Mysql中字符串正确的连接方法

    虽然SQL server和My sql的语句基本都一致,但是仍然存在一些小区别.就如字符串的连接来说,SQL server中的字符串连接是使用“+”来连接,不带引号sql server是做加法运算.而 ...

  10. Redis C客户端Hiredis代码分析

    初始化 redisContext - Redis连接的上下文 /* Context for a connection to Redis */ typedef struct redisContext { ...