sendMessage&sendEmptyMessage异同

来源:互联网 发布:有手机plc编程软件吗 编辑:程序博客网 时间:2024/05/13 16:52

      最近在做Android客户端给Tomcat服务器传输文件,Android端要显示文件上传的进度,在界面显示。文件上传任务,是交给Service开启的子线程在做,每一步传输的进度,通过MainActivity.mHandler调用sendEmptyMessage通知MainActivity进行进度条更新。

上传文件的Service进度监听如下:

while((len = in.read(buf))!=-1){    curProgress += len;    sb.append(new String(buf,0,len));    progress = (float) ((curProgress/file.length())*100.0);    Message msg = Message.obtain();    Bundle bundle = new Bundle();    bundle.putFloat("UpProgress",50);    msg.setData(bundle);    MainActivity.mHandler.sendEmptyMessage(MainActivity.UP_PROGRESS);}

MainActivity的mHandler处理如下:

mHandler = new Handler() {            @Override            public void handleMessage(android.os.Message msg) {                switch (msg.what) {                                      case UP_PROGRESS://上传进度                        Bundle bundle2 = msg.getData();                        float pro = bundle2.getFloat("UpProgress");                        //更新进度条                        upProgressBar.setProgress((int) pro);                        builder.setContentTitle("正在上传")                                .setSmallIcon(R.mipmap.ic_launcher);                        builder.setContentText("已完成"+pro+"%");                        builder.setProgress(100, (int) pro, false);                        manager.notify(100, builder.build());                        break;                }            }        };

      调试运行,发现界面的进度条并没有更新。我折腾了半天,以为服务器接收有问题或Android端发送文件有问题,导致没有获得进度。奇怪的是,后来发现文件成功上传了,PC服务器指定目录已上传成功。我回过头想,究竟是哪的问题,之前使用类似于MainActivity的mHandler处理短暂界面更新的都没问题。

   最后问题锁定在MainActivity.mHandler.sendEmptyMessage(MainActivity.UP_PROGRESS);方法上。因为之前用的都是sendMessage方法。
   查找相关资料,都说sendEmptyMessage和sendMessage两者没区别,最后还是尝试了一番,把上传文件的Service进度监听更改为:
while((len = in.read(buf))!=-1){    curProgress += len;    sb.append(new String(buf,0,len));    progress = (float) ((curProgress/file.length())*100.0);    Message msg = Message.obtain();    Bundle bundle = new Bundle();    bundle.putFloat("UpProgress",progress);    msg.setData(bundle);    msg.what = MainActivity.UP_PROGRESS;    MainActivity.mHandler.sendMessage(msg);}
改用sendMessage就OK了。这倒也奇怪,看sendMessage和sendEmptyMessage的源码:
public final boolean sendMessage(Message msg){   return sendMessageDelayed(msg, 0);}
public final boolean sendEmptyMessage(int what){   return sendEmptyMessageDelayed(what, 0);}
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {   Message msg = Message.obtain();   msg.what = what;   return sendMessageDelayed(msg, delayMillis);}

原来在sendEmptyMessageDelayed中就是构建了一个Message,然后把这个Message的what设置成sendEmptyMessage方法中的What参数即可。 然后,在主线程中,Looper类的

loop()通过 调用:msg.target.dispatchMessage(msg),调用Hanler类的dispatchMessage(Message msg)方法,从而在主线程中处理了这个Message。二者没什么区别,但在此执行,却也不解。

最后,关于使用Message的补充:

1.Message有public的默认构造方法,可以直接new Message();但是应该通过Message.obtain()来从消息池中获得空消息对象,以节省资源,这也是Google推荐的方式。

2.如果你的message只需要携带简单的int信息,请优先使用Message.arg1和Message.arg2来传递信息,这比用Bundle更省内存

3.擅用message.what来标识信息,以便用不同方式处理message。

 

 

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 3个月小宝宝咳嗽怎么办 2个月小宝宝咳嗽怎么办 8的岁儿童腿不直怎么办 作业盒子选错年级怎么办 两岁x型腿怎么办 绿萝叶子有水滴怎么办 打游戏变菜了怎么办 车被记号笔画了怎么办 水溶性彩铅受潮了怎么办 马克笔颜色涂深了怎么办 染发膏染眉毛了怎么办 用电容笔画画手有触感怎么办 CAD画图线性数字不居中怎么办 3d立体画笔堵塞怎么办 龋齿树脂填充老化后怎么办 小孩补过的牙疼怎么办 颜料弄到墙纸上怎么办 4岁的宝宝不爱涂色怎么办 oppo手机截图存不到相册怎么办 做的ih5保存不了怎么办 小偷偷东西发现后逃跑了怎么办? 网上有人传迷信诅咒怎么办 颜料粘在衣服上怎么办 家里有小偷撬锁怎么办 在家有人在撬门怎么办 6个月的宝宝腹泻怎么办 六个月大的宝宝拉肚子怎么办 六个月宝宝着凉拉肚子怎么办 六个月婴儿着凉拉肚子怎么办 怀孕六个月着凉拉肚子怎么办 六个月的婴儿消化不好怎么办 六个月婴儿不好好吃奶怎么办 六个月婴儿消化不好怎么办 六个月婴儿肠胃不好怎么办 受了惊吓后睡眠不好怎么办 宝宝夏季吃饭不爱带围嘴怎么办 3岁宝宝爱看电视怎么办 新生儿晚上哭闹不睡觉怎么办 档案丢了怎么办失业证 三岁宝宝不合群怎么办 阴唇手术半月了疤痕增生怎么办