我尝试了解功能,特别是我们通过浏览Android Studio中提供的全屏活动模板将removeCallbacks()
与postDelayed()
结合使用的一个特定原因。在全屏活动模板中,当触摸屏幕时,它将在一定的毫秒数后显示/隐藏状态栏和导航/系统栏,并且在此模板的情况下为3000毫秒。
private void hide() {
// Hide UI first
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
mControlsView.setVisibility(View.GONE);
mVisible = false;
// Schedule a runnable to remove the status and navigation bar after a delay
mHideHandler.removeCallbacks(mShowPart2Runnable); // <------ Comment/uncomment
mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
}
@SuppressLint("InlinedApi")
private void show() {
// Show the system bar
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mVisible = true;
// Schedule a runnable to display UI elements after a delay
mHideHandler.removeCallbacks(mHidePart2Runnable); // <------ Comment/uncomment
mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
}
/**
* Schedules a call to hide() in [delay] milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable); // <------ Comment/uncomment
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
我了解removeCallbacks()
用于从消息队列中删除待处理消息/ runnables,但除了符合条件之外,我们还有一个特殊原因可以使用它我们不再希望执行挂起的消息/ runnables吗?
我问这个问题,因为关于全屏活动模板我在这里感到困惑,因为如果我在使用mHideHandler.removeCallbacks(Runnable)
时没有打电话给postDelayed()
那么它就会#39} ; ll允许用户垃圾邮件隐藏/显示方法。随着垃圾邮件的发送,过渡动画似乎被中断,并且动画甚至可能在垃圾邮件期间卡住,因为它在转换期间的某个时刻停止了。但是,如果我在mHideHandler.removeCallbacks(Runnable)
之前拨打postDelayed()
,那么它会阻止用户发送隐藏/显示方法,这很好。
我想简而言之,我的问题是mHideHandler.removeCallbacks(Runnable)
如何防止在与postDelayed()
一起使用时调用方法的垃圾邮件?问题类似于question,但我希望得到解释为什么会发生这种情况。
以下是.gif格式的差异。使用removeCallbacks()是注释掉removeCallbacks()导致不想要的&#34;滥用&#34;行为:
编辑:在.gifs中添加并在代码中的removeCallbacks()中添加了注释,以帮助识别我正在谈论的代码的哪一部分。
答案 0 :(得分:3)
每次执行点击时,您都会向MessageQueue
发布一个事件,该事件将在UI_ANIMATION_DELAY
毫秒后执行(假设它是300毫秒)。
现在,当您执行连续点击时,您将以这种方式发布事件:
SHOW - HIDE - SHOW - HIDE - ...
如果您不执行removeCallbacks()
,则会执行所有这些消息,这意味着将执行每个SHOW
和HIDE
操作,这会导致这种不良行为
另一方面,当使用removeCallbacks()
时,您告诉您不再对相反的事件感兴趣,并且不希望该事件完全执行。例如,如果我们遇到系统栏显示的情况,那么下一次点击会在300毫秒后发出HIDE
事件并且您明确告诉,“嘿,如果有某些事件张贴应该SHOW
系统栏,然后取消它们“
handler.removeCallbacks(showRunnable);
handler.postDelayed(hide, 300);
这给您带来的是,每次执行连续点击事件时,队列中已发布的相反事件消息将被取消。这可以确保每次只有1条消息发布在队列中。
系统UI可见,当前消息队列:
EMPTY
点击发生:
HIDE
点击发生:
SHOW (HIDE is being removed from queue)
点击发生:
HIDE (SHOW is being removed from queue)
因此,最后,当传递300ms并且不从队列中删除此消息时,只会执行最后一个事件。