對于Android工作線程進行全解析
Android工作線程是程序中一個單一的順序控制流程.在單個程序中同時運行多個線程完成不同的工作,這些內容都是一些門戶網站和技術論壇找到的,中間可能有不少錯誤是我沒有挑出的,歡迎大家指正。
由于SurfaceHolder是一個共享資源,因此在對其操作時都應該實行“互斥操作“,即需要使用synchronized進行”封鎖“機制。再來討論下為什么要使用消息機制來更新界面的文字信息呢?其實原因是這樣的。
渲染文字的工作實際上是主線程(也就是LunarView類)的父類View的工作。而并不屬于Android工作線程LunarThread,因此在Android工作線程中式無法控制的。所以我們改為向主線程發送一個Message來代替。
讓主線程通過Handler對接收到的消息進行處理,從而更新界面文字信息。再回顧上一篇SnakeView里的文字信息更新,由于是SnakeView自己(就這一個線程)對其包含的TextView做控制,當然沒有這樣的問題了。
- public void run()
- {
- while (mRun)
- {
- Canvas c = null;
- try
- {
- //鎖定待繪制區域
- c = mSurfaceHolder.lockCanvas(null);
- synchronized (mSurfaceHolder)
- {
- if (mMode == STATE_RUNNING)
- updatePhysics();//更新底層數據,判斷游戲狀態
- doDraw(c);//強制重繪制
- }
- }
- finally
- {
- if (c != null) {
- mSurfaceHolder.unlockCanvasAndPost(c);
- }
- }
- }
- }
下面就是LunaThread這個Android工作線程的執行函數了,它一直不斷在重復做一件事情:鎖定待繪制區域(這里是整個屏幕),若游戲還在進行狀態,則更新底層的數據,然后直接強制界面重新繪制。
- canvas.save();
- canvas.rotate((float) mHeading, (float) mX, mCanvasHeight
- - (float) mY);
- if (mMode == STATE_LOSE) {
- mCrashedImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop
- + mLanderHeight);
- mCrashedImage.draw(canvas);
- } else if (mEngineFiring) {
- mFiringImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop
- + mLanderHeight);
- mFiringImage.draw(canvas);
- } else {
- mLanderImage.setBounds(xLeft, yTop, xLeft + mLanderWidth, yTop
- + mLanderHeight);
- mLanderImage.draw(canvas);
- }
- canvas.restore();
LunarLancher的暫停其實并沒有不再強制重繪制,而是沒有對底層的數據做任何修改,依然繪制同一幀畫面,而繼續則是把mLastTime設置為當前時間+100毫秒的時間點,因為以前暫停時mLastTime就不再更新了,這樣做事為了與當前時間同步起來。