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。
更多相关文章
- 获取手机联系人数据方法
- Android(安卓)webView 中loadData方法加载 带中文时出现乱码
- Android(安卓)Gradle使用笔记(持续更新)
- MediaMetadataRetriever类、方法以及使用详解
- Android学习笔记(十四)
- 如何定制PopupWindow弹出框及方法介绍
- Android中调用外部程序的方法[整理]
- Android(安卓)程式开发:(十三)特殊碎片 —— 13.2 DialogFragment
- Android(安卓)Studio 2.0代码热更新