安卓开发:点击屏幕移动圆形后其无理由异常加速问题咨询
核心问题出在OnGlobalLayoutListener没有及时移除
你的OnGlobalLayoutListener没有在首次触发后移除,每次根布局发生重绘时,都会重复触发回调,每次回调都会执行一次leHandleur.post(mover),相当于给Handler的消息队列新增一个mover执行任务。
而mover内部每次执行完都会调用leHandleur.postDelayed(this, 0)循环触发自身,所以每多一次post,后续每一轮刷新都会多执行一次移动逻辑:
- 首次触发后,每轮刷新移动1次
moverSpeed - 第二次触发回调后,每轮刷新移动2次
moverSpeed,速度翻倍 - 后续每触发一次,速度就叠加一次
你每次点击圆形时,会执行scoreTxt.setText(newScore)更新分数,如果TextView的宽高随内容变化,就会触发根布局重绘,进而触发OnGlobalLayoutListener,所以每次点击后速度都会变快。
解决方案
- 在
OnGlobalLayoutListener首次执行完成后立即移除监听器,避免重复触发:
ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { xWidth = rootLayout.getWidth() - toMove.getWidth() - moverSpeed; yHeight = rootLayout.getHeight() - toMove.getHeight() - moverSpeed; Log.d("Max_Heigth_Width", "onCreate: \nHeight: " + yHeight + "\nWidth: " + xWidth); // 启动移动逻辑前先移除已存在的回调,避免重复执行 leHandleur.removeCallbacks(mover); leHandleur.post(mover); // 移除当前监听器 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); } } }; rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
- 可选优化:你当前设置的
postDelayed延迟为0,会尽可能频繁的执行移动逻辑,建议调整为16ms(和普通60Hz屏幕的刷新周期对齐),降低不必要的性能消耗:
leHandleur.postDelayed(this, 16);
内容的提问来源于stack exchange,提问作者Tschogge
相关产品推荐
相关产品推荐

