所以我有一个带有TextView的活动来保存分数,如下所示:

public class PlayGameActivity extends Activity {
    private GameThread mGameThread;
    private GameView mGameView;

    private Handler mHandler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_play_game);

        final TextView scoreView = (TextView) findViewById(R.id.textView2);

        mGameView = (GameView) findViewById(R.id.gameView1);
        mGameThread = mGameView.getThread();

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mGameView != null) {
                    scoreView.setText(mGameThread.getScore());
                }
            }
        });
    }
}


然后在我的GameView中,我声明了如下函数:

class GameView extends SurfaceView implements SurfaceHolder.Callback {
    class GameThread extends Thread {
        int score = 0;

        public String getScore(){
            return Integer.toString(score);
        }

        @Override
        public void run() {
            synchronized (mSurfaceHolder) {
                if (something){
                    score++
                }
            }
        }
    }
}


问题是,mGameThread.getScore()始终返回0,好像分数肯定没有更新时也是如此。

如果有人煽动,我们将不胜感激。另外,我从上面的代码片段中剥离了许多不必要的代码。如果您想查看全文,可以在这里进行:


PlayGameActivity.java
GameView.java

最佳答案

使用事件/侦听器机制可以更好地更新UI数据。

坐在循环线程中不是OOP风格的编程。如果您的应用中发生了分数变化,那么您肯定有能力检测到变化。一旦检测到,通过一个简单的setText调用来更新UI到textview。

不要像通过调用post(....)那样过度拥挤UI事件队列堆栈,这会使您的UI对实际用户交互的响应降低,尤其是在定时循环中。请记住,整个系统的UI事件队列堆栈为1,它旨在处理用户与设备的交互。

如果您需要从非UI线程更改UI组件

     activity.runOnUiThread(Runnable);


方法而不是post(Runnable)。这样,您可能需要更长的时间来执行Runnable中定义的代码(尽管不建议这样做)。否则,请确保post(Runnable)中的代码可以非常快速地执行和完成。

07-28 01:12
查看更多