赞
踩
RK3288 + Android 7.1 + AndroidStudio 4.0.1
使用Handler
Handler.postDelayed(Runnable, Int)
时, Runnable.run中的代码不执行
Handler 部分的代码:
- static class H extends Handler{
- final static int MSG_REFRESH_TIME = 0;
- WeakReference<KidsLauncher> a;
- H(KidsLauncher lk){
- a = new WeakReference<>(lk);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what){
- case MSG_REFRESH_TIME:
- a.get().refreshTime();
- break;
- }
- }
-
- /*@Override
- public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
- Logger.d("sendmessageAtTime " + msg.what + " " + uptimeMillis + ":" + SystemClock.uptimeMillis());
- return super.sendMessageAtTime(msg, uptimeMillis);
- }*/
- }
-
-
- void refreshTime(){
- tvTime.setText(TimeUtils.getTimeString());
- h.removeMessages(H.MSG_REFRESH_TIME);
- h.sendEmptyMessageDelayed(H.MSG_REFRESH_TIME, 1000);
- }

尝试过的解决方案:
查阅相关源码及文章:
Handler sendMessageDelayed()/postDelayed()机制详解
尝试把上面注释代码放开, 输出LOG, 终于发现了问题所在.
原因: 在应用中, 定义一个消息类型为 MSG_REFRESH_TIME=0; 在启动后, 会自循环更新当前的时间.
考虑下这样一个问题: Handler.post后, 最终enqueueMessage时, Message.what是多少? 答案是 0
- //frameworks/base/core/java/android/os/Handler.java
-
- public final boolean postDelayed(Runnable r, long delayMillis)
- {
- return sendMessageDelayed(getPostMessage(r), delayMillis);
- }
-
-
-
- private static Message getPostMessage(Runnable r) {
- Message m = Message.obtain();
- m.callback = r;
- return m;
- }
-
- public final boolean sendMessageDelayed(Message msg, long delayMillis)
- {
- if (delayMillis < 0) {
- delayMillis = 0;
- }
- return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
-
- public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
- MessageQueue queue = mQueue;
- if (queue == null) {
- RuntimeException e = new RuntimeException(
- this + " sendMessageAtTime() called with no mQueue");
- Log.w("Looper", e.getMessage(), e);
- return false;
- }
- return enqueueMessage(queue, msg, uptimeMillis);
- }

不管是new Message(), 还是Message.obtain(), 在初始时, 基本都是0
再看下面这段代码:
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- h = new H(this);
- h.postDelayed(new Runnable() {
- @Override
- public void run() {
- Logger.d("run in post Delayed");
- }
- }, 2000);
- h.removeMessages(0);
- }
代码中 "run in post Delayed" 这个LOG, 是不会打印出来的, 原因是, Message已经从队列移除了.
同理, 在使用MSG_REFRESH_TIME 更新时间的时, 执行refreshTime后, 队列中, 所有的带Runnable的Message已经被h.removeMessages(H.MSG_REFRESH_TIME); 移出了队列.
所以这个问题是, 自己挖坑, 再把自己埋了...
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。