sendMessage&sendEmptyMessage异同

      最近在做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。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值