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

随机推荐

  1. Compile, Install, Run Linux Apps on An
  2. Intents and IntentFilters
  3. Initializing a Build Environment
  4. Build android development platform in
  5. Android(安卓)ADB命令大全
  6. adb top 指令,查看系统进程
  7. New Work Style - Mobile Smart Setting
  8. Android学习笔记-Activity的生命周期
  9. android之location02
  10. 百度新版定位无法进入MyLocationListenne