通过handler更新UI的疑问

hzvcan 2014-11-27 10:12:33
我通过子线程向UI线程发送message来更新进度条,子线程用了一个for循环,每循环一次都是向UI线程
发送消息,然后UI线程接受到消息后,就更新progressbar。
但是,实际上系统并不是按我想的去执行(子线程发消息-->UI处理-->子线程发消息-->UI处理-->....)
而是子线程发消息-->子线程发消息--->...-->UI处理-->UI处理-->UI处理-->...
而且,UI每次处理的消息,都是最后一个消息,明明我是发送了几个不同的消息的。
如果我在子线程的循环中加个Thread.sleep(100),就是子线程发消息-->UI处理-->子线程发消息-->UI处理-->....
好奇怪,求大侠指教!
UI处理的代码:
 handler=new Handler()
{
public void handleMessage(Message msg)
{
try{
switch(msg.what)
{

case 3://
int i=msg.getData().getInt("i");
progresabar1.setProgress(i);/更新进度条

break;
}
}catch(Exception e)
{

}

}


};

子线程的代码:
public void run() {

Looper.prepare();//开始消息循环qk
try{
myhandler=new Handler()
{
Bundle bd=new Bundle();
Message mg;
public void handleMessage(Message msg)
{
switch(msg.what)
{
case 3:
for(int i=3;i<=15;i++){
bd.clear();
mg=null;
mg= superHd.obtainMessage();
bd.putInt("i",i);
mg.setData(bd);
mg.what=3;
mg.arg1=msg.arg1;

superHd.sendMessage(mg);//调试发现,在没有sleep的时候,这边是连续发送了13个消息,而且接受的UI现在是在这边for循环完
//后在处理消息,而且是连续处理了13个,但是奇怪的是,这13个mg,为什么都相同呢?

Log.d("dd","fasong:"+String.valueOf(i));
/*
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/

}


break;
}
// process incoming messages here
}
};
...全文
364 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jgszhuzhu 2014-12-04
  • 打赏
  • 举报
回复
handler post runnable 百度个例子自己看看
Zoro_Xx 2014-12-04
  • 打赏
  • 举报
回复
bd.clear改成bd = new Bundle()应该就可以,我以前也经常犯这种错误
hzvcan 2014-11-29
  • 打赏
  • 举报
回复
引用 5 楼 s715575807 的回复:
[quote=引用 3 楼 hzvcan 的回复:] 就算是时间问题,那为什么我发的13个消息,在UI接受时内容都一样呢?
不好意思,昨天没看代码......bd.clear();这个可能有问题,你每次用的是一个对象bundle,而所有的message的data都是引用那个bundle,所以应该是你从头到尾用的1个bundle,之前数据都被clear,所以就是显示最后的。把bd.clear改bd = new Bundle();应该就可以了[/quote] 谢谢,改成new bundle是可以了。
hzvcan 2014-11-29
  • 打赏
  • 举报
回复
引用 4 楼 blovecat 的回复:
这个功能bu需要new 出两个handler, superHd这个又是什么,直接在主线程new 出一个handler,子线程直接在for循环里sendmessage,不需要在new handler 再在 handleMessage里for循环


如图,我用2个handler是想多个activity公用一个数据库访问线程(数据库线程有2个handler,一个保存Activity的handler,也就是superHandler,用来向Activity发消息,一个是线程本身的myhanlder,用来处理Activity发来的消息),不想每个activity都开一个。数据库线程对象
用一个全局变量保存,在Activity切换时,通过全局变量,改变hanlder的引用,麻烦你看下这样的设计是否有问题,或者是否可以优化,谢谢!
s_wenze 2014-11-28
  • 打赏
  • 举报
回复
引用 3 楼 hzvcan 的回复:
就算是时间问题,那为什么我发的13个消息,在UI接受时内容都一样呢?
不好意思,昨天没看代码......bd.clear();这个可能有问题,你每次用的是一个对象bundle,而所有的message的data都是引用那个bundle,所以应该是你从头到尾用的1个bundle,之前数据都被clear,所以就是显示最后的。把bd.clear改bd = new Bundle();应该就可以了
山雨楼 2014-11-28
  • 打赏
  • 举报
回复
这个功能bu需要new 出两个handler, superHd这个又是什么,直接在主线程new 出一个handler,子线程直接在for循环里sendmessage,不需要在new handler 再在 handleMessage里for循环
hzvcan 2014-11-28
  • 打赏
  • 举报
回复
引用 1 楼 s715575807 的回复:
handler会把消息传递到looper对象,looper对象里面有消息队列,looper会进行轮询。查看源码你可以发现是通过for循环从消息队列取出消息,再将消息发送给handlermessage方法。 轮询也需要时间,你直接新开进程for循环发消息比取出要快,所以会出现那种结果。如果你加入了sleep代码,线程暂停,looper就有足够的时间把消息发出去,最后结果就是一发一送了
就算是时间问题,那为什么我发的13个消息,在UI接受时内容都一样呢?
s_wenze 2014-11-27
  • 打赏
  • 举报
回复
handler会把消息传递到looper对象,looper对象里面有消息队列,looper会进行轮询。查看源码你可以发现是通过for循环从消息队列取出消息,再将消息发送给handlermessage方法。 轮询也需要时间,你直接新开进程for循环发消息比取出要快,所以会出现那种结果。如果你加入了sleep代码,线程暂停,looper就有足够的时间把消息发出去,最后结果就是一发一送了
什么是SWFUpload?   SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术为WEB开发者提供了一个具有丰富功能继而超越传统标签的文件上传模式。 [编辑本段]SWFUpload的主要特点   * 可以同时上传多个文件;   * 类似AJAX的无刷新上传;   * 可以显示上传进度;   * 良好的浏览器兼容性;   * 兼容其他JavaScript库 (例如:jQuery, Prototype等);   * 支持Flash 8和Flash 9;   SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,开发者可以利用XHTML、CSS和JavaScript来随心所欲的定制它在浏览器下的外观;它还提供了一组简明的JavaScript事件,借助它们开发者可以方便的在文件上传过程中更新页面内容来营造各种动态效果。   在使用SWFUpload之前,请确认你具备一定的JavaScript和DOM知识。在实际开发中,大部分的错误都是由于错误的设置和低劣的Event Handlers处理程序所造成的。 [编辑本段]文档中文翻译   http://www.v-sky.com/doc/swfupload/v2.1.0/Documentation.html [编辑本段]效果演示   * Classic Form Demo http://demo.swfupload.org/formsdemo ;   * Features Demo http://demo.swfupload.org/featuresdemo ;   * Application Demo http://demo.swfupload.org/applicationdemo ;   * v1.0.2 Plugin Demo http://demo.swfupload.org/v102demo ; [编辑本段]选择合适的Flash控件   在发行包(SWFUpload v2)中含有2个版本的Flash控件(swfupload_f8.swf 与wfupload_f9.swf),其中第一个版本拥有最佳的兼容性,但是为此损失了部分功能;而第二个版本提供了一些附加的功能但是损失了兼容性。 [编辑本段]SWFUpload的初始化与配置   首先,在页面中引用SWFUpload.js ,如      然后,初始化SWFUpload ,如   var swfu;   window.onload = function () {   swfu = new SWFUpload({   upload_url : "http://www.swfupload.org/upload.php",   flash_url : "http://www.swfupload.org/swfupload_f9.swf", file_size_limit : "20480"   });   };   以下是一个标准的SWFUpload初始化设置所需的参数,你可以根据需要自己进行删减:   {   upload_url : "http://www.swfupload.org/upload.php", 处理上传请求的服务器端脚本URL   file_post_name : "Filedata", 是POST过去的$_FILES的数组名   post_params : {   "post_param_name_1" : "post_param_value_1",   "post_param_name_2" : "post_param_value_2",   "post_param_name_n" : "post_param_value_n"   },   file_types : "*.jpg;*.gif", 允许上传的文件类型   file_types_description: "Web Image Files", 文件类型描述   file_size_limit : "1024", 上传文件体积上限,单位MB   file_upload_limit : 10, 限定用户一次性最多上传多少个文件,在上传过程中,该数字会累加,如果设置为“0”,则表示没有限制   file_queue_limit : 2, 上传队列数量限制,该项通常不需设置,会根据file_upload_limit自动赋值   fl

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧