场景:想实现一个每隔1s就循环发送消息的功能,没注意用了sendEmptyMessageAtTime,结果程序跑了一会就挂了,没道理呀!
发现消息
mHandler.sendEmptyMessageAtTime(MSG_UPDATA_PROGRESS,MSG_UPDATA_DELAY);
收到之后再次发送消息
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//更新播放进度
if (msg.what==MSG_UPDATA_PROGRESS){
// 获得当前播放时间和当前视频的长度
int currentPosition = mVideoView.getCurrentPosition();
int duration = mVideoView.getDuration();
int time = ((currentPosition * 100) / duration);
// 设置进度条的主要进度,表示当前的播放时间
mSeekBar.setProgress(time);
mHandler.sendEmptyMessageAtTime(MSG_UPDATA_PROGRESS,MSG_UPDATA_DELAY); //循环发送崩溃
}
super.handleMessage(msg);
}
};
仔细研究二者的区别才发现问题所在:sendEmptyMessageAtTime是在指定时间发送,也就是说你循环调用,但是最终还是在同一时刻发送,所以最终的结果是导致大量的消息在同一时刻被发送和处理,当然就挂了。
- sendEmptyMessageAtTime源码
/**
* Sends a Message containing only the what value, to be delivered
* at a specific time.
* @see #sendMessageAtTime(android.os.Message, long)
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
其中
Sends a Message containing only the what value, to be delivered
at a specific time
说的很清楚,在特定的时间MSG_UPDATA_DELAY也就是1s被发送
源码
/**
* Sends a Message containing only the what value, to be delivered
* after the specified amount of time elapses.
* @see #sendMessageDelayed(android.os.Message, long)
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
说的是
Sends a Message containing only the what value, to be delivered
after the specified amount of time elapses.
指定时间之后才发送,也就是说我隔1s再发送,收到之后再隔1s再发送。
最后解决办法:把mHandler.sendEmptyMessageAtTime(MSG_UPDATA_PROGRESS,MSG_UPDATA_DELAY);
改成 mHandler.sendEmptyMessageDelayed(MSG_UPDATA_PROGRESS,MSG_UPDATA_DELAY);
就好了。
总结:
1.sendEmptyMessageAtTime(what, inMillis)是在固定时间发送消息,其中第二个参数是已开机时间为准,可能你开机时间到现在已经超过了5S,所以就立即执行了
2.sendMessageAtTime的uptimeMillis是相对系统开机时间的绝对时间,SystemClock.uptimeMillis()是当前开机时间。
3.这两句是等效的,都是延时1秒将消息加入列队
msgHandle.sendMessageAtTime(msg, SystemClock.uptimeMillis()+1000);
msgHandle.sendMessageDelayed(msg, 1000)
如果本文对你有帮助,就关注下作者吧,点此查看全部最新文章
博客CSDN
我的简书
我的GitHub,喜欢的话给个star吧