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