Android开发学习—— 消息队列
###主线程不能被阻塞
* 在Android中,主线程被阻塞会导致应用不能刷新ui界面,不能响应用户操作,用户体验将非常差
* 主线程阻塞时间过长,系统会抛出ANR异常
* ANR:Application Not Response;应用无响应
* 任何耗时操作都不可以写在主线程
* 因为网络交互属于耗时操作,如果网速很慢,代码会阻塞,所以网络交互的代码不能运行在主线程
###只有主线程能刷新ui
* 刷新ui的代码只能运行在主线程,运行在子线程是没有任何效果的
* 如果需要在子线程中刷新ui,使用消息队列机制
###消息队列
* Looper一旦发现Message Queue中有消息,就会把消息取出,然后把消息扔给Handler对象,Handler会调用自己的handleMessage方法来处理这条消息
* handleMessage方法运行在主线程
* 主线程创建时,消息队列和轮询器对象就会被创建,但是消息处理器对象,需要使用时,自行创建
消息机制的原理图:

使用handler的一般步骤:
public class MainActivity extends Activity {
1.在主线程中创建handler成员变量对象,并重写其handlerMessage()
Handler handler = new Handler(){
//此方法在主线程中调用,可以用来刷新UI
//主线程中有一个消息轮询器looper,不断检测消息队列中是否有新消息,如果发现有新消息,自动调用此方法,注意此方法是在主线程中运行的
4.在handleMessage()中处理消息
public void handleMessage(android.os.Message msg) {
// 通过switch语句区分不同的消息
switch (msg.what) {
//如果是1,说明属于请求成功的消息
case 1:
ImageView iv = (ImageView) findViewById(R.id.iv);
Bitmap bm = (Bitmap) msg.obj;
iv.setImageBitmap(bm);
break;
case 2:
Toast.makeText(MainActivity.this, "请求失败", 0).show();
break;
} } };
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View v) throws IOException{
Thread t = new Thread(){
public void run(){
//确定网址
String imgurl="http://127.0.0.1:8080/dd.jpg";
try {
//把网址封装册为url对象
URL url = new URL(imgurl);
//获取客户端和服务器端的连接对象,此时还没有建立连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//对连接对象进行初始化,设置请求方法
try {
conn.setRequestMethod("GET");
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn.setConnectTimeout(5000);//5s超时
conn.setReadTimeout(5000);//读取超时,网址是对的。
//发送请求,与服务器建立连接
conn.connect();
//请求成功,服务器会返回一个流
if(conn.getResponseCode()==200){
InputStream is = conn.getInputStream();
Bitmap bm = BitmapFactory.decodeStream(is);//读取流里的数据并构造位图对象
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bm);
加入缓存图片的功能
* 把服务器返回的流里的数据读取出来,然后通过文件输入流写至本地文件
//1.拿到服务器返回的输入流
InputStream is = conn.getInputStream();
//2.把流里的数据读取出来,并构造成图片
FileOutputStream fos = new FileOutputStream(file);
byte[] b = new byte[1024];
int len = 0;
while((len = is.read(b)) != -1){
fos.write(b, 0, len);
}
* 创建bitmap对象的代码改成
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
* 每次发送请求前检测一下在缓存中是否存在同名图片,如果存在,则读取缓存
//在子线程中往消息队列里发消息
2.在分线程中创建message对象
//创建消息对象
Message msg = new Message();
//消息的obj属性可以赋值任何对象,通过这个属性可以携带数据
msg.obj = bm;
//what属性相当于一个标签,用于区分出不同的消息,从而运行不能的代码
msg.what = 1;
//3.使用handler对象发送消息
handler.sendMessage(msg);
}else{
//创建消息对象
Message msg = handler.obtainMessage();
//消息的obj属性可以赋值任何对象,通过这个属性可以携带数据
//what属性相当于一个标签,用于区分出不同的消息,从而运行不能的代码
msg.what =0 ;
//发送消息
handler.sendMessage(msg);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();
}
}

Android开发学习—— 消息队列的更多相关文章
- Android开发学习—— 消息机制
###主线程不能被阻塞* 在Android中,主线程被阻塞会导致应用不能刷新ui界面,不能响应用户操作,用户体验将非常差* 主线程阻塞时间过长,系统会抛出ANR异常* ANR:Application ...
- Android开发学习总结(一)——搭建最新版本的Android开发环境
Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...
- Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
- Android开发学习路线图
Android开发学习方法: Android是一个比较庞大的体系,从底层的Linux内核到上层的应用层,各部分的内容跨度也比较大.因此,一个好的学习方法对我们学习Android开发很重要. 在此建议, ...
- android开发学习笔记000
使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...
- Android开发学习之LauncherActivity开发启动的列表
Android开发学习之LauncherActivity开发启动的列表 创建项目:OtherActivity 项目运行结果: 建立主Activity:OtherActivity.java [jav ...
- 最实用的Android开发学习路线分享
Android开发学习路线分享.Android发展主导移动互联发展进程,在热门行业来说,Android开发堪称火爆,但是,虽然Android有着自身种种优势,但对开发者的专业性要求也是极高,这种要求随 ...
- Android开发学习必备的java知识
Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...
- Android开发学习之路--基于vitamio的视频播放器(二)
终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...
随机推荐
- 归并排序的java实现
归并排序的优点不说了. 做归并排序之前,我先试着将两个有序数组进行排序,合并成一个有序数组. 思路:定义好两个有序数组,理解的时候我先思考了数组只有一个数组的排序,然后是两个元素的数组的排序,思路就有 ...
- .NET Core 1.0.1 升级汇总
ASP.NET Core BUG fix: ASP.NET Routing Port fix for "Request not matching route with defaults&qu ...
- 【Java并发编程实战】-----“J.U.C”:Phaser
Phaser由java7中推出,是Java SE 7中新增的一个使用同步工具,在功能上面它与CyclicBarrier.CountDownLatch有些重叠,但是它提供了更加灵活.强大的用法. Cyc ...
- ABP源码分析三十:ABP.RedisCache
ABP 通过StackExchange.Redis类库来操作Redis数据库. AbpRedisCacheModule:完成ABP.RedisCache模块的初始化(完成常规的依赖注入) AbpRed ...
- ABP框架 - 多租户
文档目录 本节内容: 什么是多租户 多部署 - 多数据库 单部署 - 多数据库 单部署 - 单数据库 单部署 - 混数据库 多部署 - 单/多/混 数据库 ABP中的多租户 启用多租户 宿主与租户 会 ...
- Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询
问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...
- salesforce 零基础学习(五十四)常见异常友好消息提示
异常或者error code汇总:https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_con ...
- vue源码解析阅读列表
https://zhuanlan.zhihu.com/p/24435564 开发vue(或类似的MVVM框架)的过程中,需要面对的主要问题有哪些? 剖析vue实现原理,自己动手实现mvvm 官网介绍
- 【Win 10应用开发】AdaptiveTrigger在自定义控件中是可以触发的
前些天,看到有网友给我留言,说AdaptiveTrigger在自定义控件(模板化控件)中不能触发.因为当时我正在写其他的代码,就没有去做实验来验证,于是我就给这位网友提了使用GotoVisualSta ...
- [C#] 走进异步编程的世界 - 剖析异步方法(上)
走进异步编程的世界 - 剖析异步方法(上) 序 这是上篇<走进异步编程的世界 - 开始接触 async/await 异步编程>(入门)的第二章内容,主要是与大家共同深入探讨下异步方法. 本 ...