【技术博客】利用handler实现线程之间的消息传递

一、handler简介

在Android Studio的开发中,经常需要启动多个线程。比如向远程发送请求时,必须新开一个子线程,否则会造成程序崩溃。这样一来发送请求后得到的远程服务器的返回信息,也仅反馈给了子线程,那么如果要将该消息传递到主线程,就需要使用handler来解决。

二、简单实例

在如下代码中,首先在主线程中new一个handler

@SuppressLint("HandlerLeak")final Handler handler=new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
String text = (String) msg.obj;
}
};

接着新建一个线程并让该线程开始,利用Message存储需要传递的信息,使用handler.sendMessage()方法,即可将消息返回给主线程。如上代码,调用msg.obj,即可在主线程中得到传递的消息。

 new Thread(){
@Override
public void run() {
super.run();
try {
Message message1 = Message.obtain();
message1.what= what;
message1.obj = result;//这是需要传递的信息
handler.sendMessage(message1);
} catch (IOException e) {
e.printStackTrace();
} }
}.start();

三、注意事项

由于handler是用于不同线程之间的,所以线程安全问题是非常重要的。

1、线程安全

message.what用来标识不同的消息,当需要返回多条消息时,该标识起很大作用。另外当多个handler同时发消息时,最好也加上.what标识加以区分返回的消息。

2、多个线程间的同步问题

首先注意,handler返回的消息在handleMessage方法内部,也就是说当你需要在主线程中获取消息时,必须在handleMessage方法内部,之后的所有逻辑代码也都在该方法内部进行。当出现多个handler同时发消息时,消息返回的顺序是不一定的。很可能会出现后开启的线程先发送了消息,与预期结果不符合得情况。所以要尽量避免多个handler进行调用,控制好多个线程间的同步问题。

3、handler的嵌套

因为我们团队进行的是博客园APP的开发,所以需要向博客园提供的API中发送不同请求。其中有些请求如下图所示。

可以看出它返回的博文列表是根据页码和页容量变化的,而且经过测试发现页容量最大是100。那么当博文列表多于100时,很显然需要增加页码的值,多次调用该API。而如我上文提到的发送请求调用API是需要新开一个线程的,这样就出现了第二个注意事项中提到的问题,多个handler同时进行调用。我们找到的解决办法时通过handler之间的嵌套解决。代码如下:

 ......
@SuppressLint("HandlerLeak")final Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg){
super.handleMessage(msg);
String text=(String)msg.obj;
@SuppressLint("HandlerLeak")final Handler handler1=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
String text=(String)msg.obj;
});
}
}
if(page>0) {
for(int i=0;i<page;i++){
getApi(handler1);
}
}
else{}
};
getApi(handler);

getApi为我们团队所写的发送Get请求的方法,其中传递了handler用来传递信息,在内部新开一个线程发送请求。

简单看一下上面代码的逻辑,首先进行到getApi,传递了handler,接着到handler的handleMessage中,得到返回的消息,进行逻辑判断,如果博客数量大于100,则page显然大于0,根据page数量继续调用getApi,但这次传递的是handler1,在handler1中的额handMessage方法中,得到了需要的数据,将它正常存储即可。这样一个简单的逻辑,在多次发送Get请求时,实则只有一个子线程进行运转,只有一个handler返回了信息,所以可以正确得到我们期望的返回信息。

最新文章

  1. html的meta总结,html标签中meta属性使用介绍
  2. 决策树(含python源代码)
  3. 分享:写了一个 java 调用 C语言 开发的动态库的范例
  4. 让nodeJS支持ES6的词法----babel的安装和使用
  5. javascript 2048游戏
  6. 第一篇T语言实例开发(版本5.3),带错误检测的加减乘除运算器
  7. OC10_代理反向传值
  8. CSS 背景图片的定位和缩放
  9. 解决弹出的窗口window.open会被浏览器阻止的问题(自定义open方法)
  10. 九度OJ 1351 数组中只出现一次的数字
  11. &lt;Win32_17&gt;集音频和视频播放功能于一身的简易播放器
  12. Spring MVC 的文件下载
  13. python3 第二十一章 - 函数式编程之return函数和闭包
  14. 【前端】wangEditor(富文本编辑器) 简易使用示例
  15. 【调试基础】Part 5 PE格式
  16. HDU - 4858 项目管理
  17. [TJOI2014]拼图
  18. Python中操作Redis
  19. Java第五次实验
  20. Python处理数据

热门文章

  1. JDK 1.7 正式发布,Oracle 官宣免费提供!“新版任你发,我用JDK 8”或成历史?
  2. Java实现发送邮件,图片,附件
  3. Markdown快捷键详解(源自狂神说Java视频,整理版)
  4. mysql升级-rpm安装
  5. Spring Boot 2.x 之 Logging
  6. 集合Collection ----List集合
  7. dede调用数据时,字符串替换函数使用
  8. Java面向对象系列(4)- 类与对象的创建
  9. IDEA - 2019中文版安装教程
  10. php stream 流封装协议