常见的.postDelayed(runnable, time)方法就是常见的延迟处理的方法之一,postDelayed(mRun,time);当想要需要取消的时候,调用removeCallbacks(mRun);即可,就可以取消postDelayed的方法里面的runnable,当然如果里面runnable已经执行了,那就不可能撤回或者中止了。
http://blog.csdn.net/bluewindtalker/article/details/51984300
下面是布局文件
<span style="font-size:18px;"> <Button
android:id="@+id/btn_demo_removecallback_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始postdelayed" />
<Button
android:id="@+id/btn_demo_removecallback_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试removecallback" />
<TextView
android:id="@+id/tv_demo_removecallback_test_onAnimationEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试removecallback runnable效果" /></span>
以下是测试代码。
<span style="font-size:18px;">final TextView mRemovecallbackTV = (TextView)findViewById(R.id.tv_demo_removecallback_test_onAnimationEnd);
mRun = new Runnable() {
@Override
public void run() {
if(DirectionMarqueeDemoActivity.this.isFinishing()){
BlueLog.e(TAG,"DirectionMarqueeDemoActivity isFinishing ");
mMarqueeAnimationTV.clearAnimation();
mRemovecallbackTV.removeCallbacks(mRun);
}
BlueLog.e(TAG, "Runnable " + DirectionMarqueeDemoActivity.this);
mRemovecallbackTV.postDelayed(this, 3000);
}
};
findViewById(R.id.btn_demo_removecallback_start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRemovecallbackTV.postDelayed(mRun, 3000);
BlueLog.e(TAG, " postDelayed " );
}
});
findViewById(R.id.btn_demo_removecallback_stop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRemovecallbackTV.removeCallbacks(mRun);
BlueLog.e(TAG, "removeCallbacks ");
}
});</span>
其中mRun为Activity的成员变量。
运行的时候我们发现
即使activity 结束了调用了onDestory方法后这里仍然运行,问题在于代码中,先removeCallBacks,再postDelayed,这里加一个return就好,
正确的代码大家就在removeCallBacks加入return即可,下面是logcat的打印
所以如要要循环调用postDelayed的时候,一样要进行判断是否所属的activity已经退出了。将结束方法一定要体现出来
而postDelayed(runnable, time)有view.postDelayed(mRun, time);和new Handler().postDelayed(mRun,time);这两种,
对于view.postDelayed我们通过源码发现
public boolean postDelayed(Runnable action, long delayMillis) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.postDelayed(action, delayMillis);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
return true;
}
return attachInfo.mHandler.postDelayed(action, delayMillis);最后进入了Handler的postDelayed
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
而ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);进入ViewRootImpl.java中,
static final class RunQueue {
private final ArrayList<HandlerAction> mActions = new ArrayList<HandlerAction>();
void post(Runnable action) {
postDelayed(action, 0);
}
void postDelayed(Runnable action, long delayMillis) {
HandlerAction handlerAction = new HandlerAction();
handlerAction.action = action;
handlerAction.delay = delayMillis;
synchronized (mActions) {
mActions.add(handlerAction);
}
}
void removeCallbacks(Runnable action) {
final HandlerAction handlerAction = new HandlerAction();
handlerAction.action = action;
synchronized (mActions) {
final ArrayList<HandlerAction> actions = mActions;
while (actions.remove(handlerAction)) {
// Keep going
}
}
}
void executeActions(Handler handler) {
synchronized (mActions) {
final ArrayList<HandlerAction> actions = mActions;
final int count = actions.size();
for (int i = 0; i < count; i++) {
final HandlerAction handlerAction = actions.get(i);
handler.postDelayed(handlerAction.action, handlerAction.delay);
}
actions.clear();
}
}
最后仍然执行了handler.postDelayed(handlerAction.action, handlerAction.delay),所以两个内容是相差无几的。
其中HandlerAction来自于view调用invalidate时,父View传入的。