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



















