关于handler在子线程中无法给activity传递信息的问题及解决办法

来源:互联网 发布:md5解密算法java 编辑:程序博客网 时间:2024/06/05 05:19

遇到一个问题,我在与服务器交互信息时,开启了另一个线程,并未这个线程(子线程)传入了handler,得到服务器返回的结果后,我开启了Looper,然后调用handler.sendMessage()想把message传回个主线程的activity,结果失败了,并没有传回到activity去:

                Looper.prepare();                Toast.makeText(context, object.get("Message").getAsString(), Toast.LENGTH_SHORT).show();                Looper.loop();                handler.sendMessage(message);


查了资料才搞懂,原来:

1.Looper:(相当于隧道) 一个线程可以产生一个Looper 对象,由它来管理此线程里的Message Queue( 车队,消息隧道) 。

2.Handler: 你可以构造Handler 对象来与Looper 沟通,以便push 新消息到Message Queue 里;或者接收Looper( 从Message Queue 取出) 所送来的消息。

3. Message Queue( 消息队列): 用来存放线程放入的消息。

4 .线程:UI thread 通常就是main thread ,而Android 启动程序时会替它建立一个Message Queue 。

每一个线程里可含有一个Looper 对象以及一个MessageQueue 数据结构。在你的应用程序里,可以定义Handler 的子类别来接收Looper 所送出的消息。

 

在你的Android 程序里,新诞生一个线程,或执行 (Thread) 时,并不会自动建立其Message Loop 。Android 里并没有Global 的Message Queue 数据结构,线程A 的Message Queue 里的讯息,只有线程A 所属的对象可以处理。


测试发现,如果把handler.sendMessage(message)放在Looper.prepare()前面是可以传回消息的。

我的理解是:在开启子线程时,并没有自动生成另外一个消息队列,这时候sendMessage后仍然会把message传入主线程的消息队列,这样在主线程中是可以接收到的。但是在执行了Looper.prepare()方法跟Looper.loop()方法后,在子线程中创建了一个消息队列,之后再sendMessage,就会将message传入到子线程的消息队列中去,而不是传回到主线程的消息队列去,所以activity并不会接收到message。,导致出现问题。

解决方法:将sendMessage方法放在Looper.prepare()方法之前调用。,或者改用其他方法不在子线程中修改主线程的内容(即:取消掉使用Looper)。







0 0
原创粉丝点击