androidのスレッドパッケージング(Thread)


簡単にandroidのスレッドに対するc++パッケージを書きます~~実はAPIはすでにはっきり書いています~~パッケージのファイル:/frameworks/base/include/utils/threads.hここでは具体的な実現については議論しないが、具体的な実装は、システムに関連付けられた~まず、Anroidは、inline bool createThread(thread_func_t f,void*a)inline bool createThreadEtcというスレッドを直接作成する関数をいくつか提供する.(thread_func_t entryFunction,                             void *userData,                             const char* threadName = "android:unnamed_thread",                             int32_t threadPriority = PRIORITY_DEFAULT,                             size_t threadStackSize = 0,                             thread_id_t *threadId = 0) inline thread_id_t getThreadId()次はAndroidのmutexを見てみましょう.基本的にposixのmutexに似ていますが、唯一Mutex::Autolockが追加されました.この自動ロックは比較的多く使われています.役割ドメインにロックを加えると、役割ドメインから離れると自動的にロックが解除されます.class Autolock {     public:         inline Autolock(Mutex& mutex) : mpMutex(&mutex) { mutex.lock(); }         inline Autolock(Mutex* mutex) : mpMutex(mutex) { mutex->lock(); }         inline ~Autolock() { mpMutex->unlock(); }     private:         Mutex*  mpMutex;     }; AndoridのConditionを見てみると、使い方は基本的にposixとあまり差がありません.それ自体が条件変数なのでmutexパラメータが1つしかありません~~最後にandroidのthreadクラスを見てみると、実際に使っているうちにこのthreadクラスを継承して自分のthreadクラスを作成し、スレッドの実行内容を定義します.次に、自分のスレッドクラスを作成するために実装する必要があるいくつかの関数をめぐって説明します.class Thread:virtual public RefBaseはまずRefBaseクラスから継承され、一般的にはonFirstRef()という親関数を実装します.一般的な古典的な使い方は、Threadのrun関数を実行し、threadのインスタンスを作成するときにこのスレッドを実行します.もちろん、ここでrun()関数を実行せず、他の場所でrun()関数を実行してこのスレッドを起動することもできます.    virtual status_t    run(    const char* name = 0,                                 int32_t priority = PRIORITY_DEFAULT,                                 size_t stack = 0); threadインスタンスを作成すると、スレッドは実行されず、run()関数を実行するときにのみ、スレッドが本格的に実行を開始します.virtual status_t    readyToRun(); この関数はthread実行前の初期化作業virtual bool threadLoop()=0を定義する.この関数は各スレッドクラスで実装され、ここでthreadの実行内容を定義します.この関数がtrueを返すと、関数はthreadloopの内容を繰り返し実行し、この関数がfalseを返すと、threadloopの内容はスレッドを1回だけ実行すると終了します.
/*
 * Android       
 */
class Thread : virtual public RefBase
{
public:
                        Thread(bool canCallJava = true);
                        virtual             ~Thread();

                        /*     ,            threadLoop()    */
                         virtual status_t    run(    const char* name = 0,
                                int32_t priority = PRIORITY_DEFAULT,
                                size_t stack = 0);
    
                         /*       (        ) */
                        virtual void        requestExit();

                        /*                 ,        */
                        virtual status_t    readyToRun();
    
                        /*       (   ) */
                        status_t    requestExitAndWait();

protected:
                        /*   requestExit()       */
                        bool        exitPending() const;
    
private:
                        /*     。      true, requestExit()              ;   false,
                        *             
                        */
                        virtual bool        threadLoop() = 0;

private:
                        Thread& operator=(const Thread&);
                        static  int             _threadLoop(void* user);
                        const   bool            mCanCallJava;
                        thread_id_t     mThread;
                        Mutex           mLock;
                        Condition       mThreadExitedCondition;
                        status_t        mStatus;
                        volatile bool           mExitPending;
                         volatile bool           mRunning;
                        sp<Thread>      mHoldSelf;
#if HAVE_ANDROID_OS
                        int             mTid;
#endif
};

適用例:
    class PreviewShowFrameThread : public Thread {
        CameraHal* mHardware;
    public:
        PreviewShowFrameThread(CameraHal* hw)
            : Thread(false), mHardware(hw) { }
        virtual void onFirstRef() {
            run("CameraPreviewShowFrameThread", PRIORITY_URGENT_DISPLAY);
        }
        virtual bool threadLoop() {
            mHardware->previewShowFrameThread();
            // loop until we need to quit
            return true;
        }
    };

    sp<PreviewShowFrameThread>   mPreviewShowFrameThread;
    mPreviewShowFrameThread = new PreviewShowFrameThread(this);