调用notifyDataSetChanged()后GridView无法立即更新问题求助
解决GridView点击后不立即更新的问题
嗨,这个问题我太熟悉了!核心原因是Android的UI操作和耗时计算不能在同一个线程(主线程)里挤着干——你现在的代码里,notifyDataSetChanged()确实告诉GridView该更新了,但紧接着调用的findBestMove()是个耗时操作,它会把主线程完全占住,导致GridView的刷新任务一直排队,直到计算完成才能执行。
解决方案:把机器人的计算放到子线程里
我们需要把耗时的minimax计算从主线程挪出去,让主线程能专心处理UI更新。这里有两种简单的实现方式:
方式一:用AsyncTask(适合Java代码)
先写一个异步任务类,专门处理机器人的计算:
private class BotMoveTask extends AsyncTask<Void, Void, Integer> { @Override protected Integer doInBackground(Void... voids) { // 这里在子线程执行耗时的minimax算法,返回最佳落子位置 return findBestMove(); } @Override protected void onPostExecute(Integer nextMove) { super.onPostExecute(nextMove); // 回到主线程,处理机器人落子和UI更新 put(true, nextMove); // 假设true代表机器人(O) chessAdapter.notifyDataSetChanged(); // 重新启用GridView,允许用户后续操作 gridviewBoard.setEnabled(true); // 这里可以加游戏结束的判断逻辑(比如检查胜负、平局) } }
然后修改你的点击事件:
gridviewBoard.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { if (isLegal(false, i)) { // 用户落子 put(false, i); // 立即通知GridView更新 chessAdapter.notifyDataSetChanged(); // 暂时禁用GridView,防止用户在机器人计算时重复点击 gridviewBoard.setEnabled(false); // 启动异步任务,让机器人在子线程计算 new BotMoveTask().execute(); } } });
方式二:用Thread + Handler(更轻量)
如果不想写AsyncTask,也可以直接用线程加主线程回调:
gridviewBoard.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { if (isLegal(false, i)) { put(false, i); chessAdapter.notifyDataSetChanged(); gridviewBoard.setEnabled(false); // 开启子线程计算最佳落子 new Thread(new Runnable() { @Override public void run() { final int nextMove = findBestMove(); // 切回主线程更新UI gridviewBoard.post(new Runnable() { @Override public void run() { put(true, nextMove); chessAdapter.notifyDataSetChanged(); gridviewBoard.setEnabled(true); } }); } }).start(); } } });
为什么这样能解决问题?
调用notifyDataSetChanged()后,主线程会收到UI刷新的请求,但如果紧接着被耗时操作占住,它就没时间处理刷新。把计算放到子线程后,主线程能立刻去处理GridView的刷新,用户就能马上看到自己的落子,而机器人的计算在后台悄悄完成,等计算结束再回到主线程处理机器人的落子。
另外,禁用GridView点击是个很重要的细节——避免用户在机器人计算时重复点击,导致棋盘数据混乱。
内容的提问来源于stack exchange,提问作者TaQuangTu
相关产品推荐
相关产品推荐

