sendEmptyMessageAtTime和sendEmpty

2017-10-22  本文已影响0人  程序员学园

场景:想实现一个每隔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是在指定时间发送,也就是说你循环调用,但是最终还是在同一时刻发送,所以最终的结果是导致大量的消息在同一时刻被发送和处理,当然就挂了。

    /**
     * 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吧
上一篇 下一篇

猜你喜欢

热点阅读