关于SurfaceView主线程与UI线程的问题

       好久没更新博客了,最近工作太忙了,也没什么时间自己研究技术,分享一点工作里总结的经验吧。

       大家都知道做Android游戏用SurfaceView效率比较高,但是需要独立的一个线程去控制绘制以及游戏逻辑。但是UI界面的触摸、按键之类的是属于UI线程的,这里就涉及到线程同步的问题。当然,代码写得小心,异步也完全没问题,效率也比较高。只不过情况有时候很复杂,未必小心就有用。

       我的方法是用一个队列保存事件,在游戏线程检索这个队列,当然要进行同步操作。以下为部分代码(按键事件省去了,与触摸同理。Logic是游戏逻辑对象,这里没有给出定义,应该一看就明白了吧:)

private ArrayList<MotionEvent> touchEventList;
   
    /**
     * 触摸事件同步锁
     */
    private byte[] touchLock = new byte[0];
 
    public boolean onTouchEvent(MotionEvent event)
    {
        synchronized (touchLock)
        {
            if (touchEventList.size() > MAX_EVENT)
            {
                touchEventList.remove(0);
            }
            touchEventList.add(MotionEvent.obtain(event));
    ​    ​    ​//注意,因为event对象不是临时的,在UI线程中其属性会随时被改变,这里需要进行深拷贝
        }
        return true;
    }
 
     public void run()
    {
        while (true)
        {
            Canvas canvas = surfaceHolder.lockCanvas();
           
            if (canvas == null)
            {
                break;
            }
            
            super.draw(canvas);
            if (logic != null)
            {
                logic.paint(canvas);
                logic.update();
               
                synchronized (touchLock)
                {
                    for (TouchAction touchAction : touchEventList)
                    {
                        logic.onTouchEvent(touchAction);
                    }
                    touchEventList.clear();
                }
            }     
            surfaceHolder.unlockCanvasAndPost(canvas);
        }
    }

转载注明出处,谢谢。

相关推荐