###主线程不能被阻塞
* 在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开发学习—— 消息队列的更多相关文章

  1. Android开发学习—— 消息机制

    ###主线程不能被阻塞* 在Android中,主线程被阻塞会导致应用不能刷新ui界面,不能响应用户操作,用户体验将非常差* 主线程阻塞时间过长,系统会抛出ANR异常* ANR:Application ...

  2. Android开发学习总结(一)——搭建最新版本的Android开发环境

    Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...

  3. Android开发学习之路-RecyclerView滑动删除和拖动排序

    Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...

  4. Android开发学习路线图

    Android开发学习方法: Android是一个比较庞大的体系,从底层的Linux内核到上层的应用层,各部分的内容跨度也比较大.因此,一个好的学习方法对我们学习Android开发很重要. 在此建议, ...

  5. android开发学习笔记000

    使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...

  6. Android开发学习之LauncherActivity开发启动的列表

    Android开发学习之LauncherActivity开发启动的列表 创建项目:OtherActivity 项目运行结果:   建立主Activity:OtherActivity.java [jav ...

  7. 最实用的Android开发学习路线分享

    Android开发学习路线分享.Android发展主导移动互联发展进程,在热门行业来说,Android开发堪称火爆,但是,虽然Android有着自身种种优势,但对开发者的专业性要求也是极高,这种要求随 ...

  8. Android开发学习必备的java知识

    Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...

  9. Android开发学习之路--基于vitamio的视频播放器(二)

      终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...

随机推荐

  1. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  2. SSH隧道应用, 突破网络限制

    文/怡文圣美 这篇文章可以帮你解决下面三个问题: 不能直连服务器, 要先登陆跳板机, 造成客户端工具无法连接服务器. 服务器没有公网IP, 且只允许公司IP访问, 要在家里操作要先远程桌面到工作机再登 ...

  3. Spring Boot -- Start Up

    做Java Web的同学,都知道项目启动需要放到servlet容器里面运行,无论是使用哪一款IDE,都是非常麻烦的一件事情.在很早之前,一个servlet容器下可以放下很多的项目,并一起运行,而到现在 ...

  4. 使用R画地图数据

    用R画地图数据 首先,从这里下载中国地图的GIS数据,这是一个压缩包,完全解压后包含三个文件(bou2_4p.dbf.bou2_4p.shp和bou2_4p.shx),将这三个文件解压到同一个目录下. ...

  5. 戴尔灵越15-5000/3558等系列修改BIOS设置U盘启动

    今天在电脑群遇到一个群友的机型是戴尔灵越15-5000,他问我这款机器怎么设置U盘启动. 看到它的BIOS界面之后,我来了点兴趣.. 本文供图:辽宁沈阳-打老虎(921407164) 电脑群:电脑爱好 ...

  6. DUILIB入门使用说明整理

    整理自博客上对DUILIB的操作使用的博客文章 一.DuiLib操作入门 1.DuiLib入门简明教程 -- 前言 2.DuiLib入门简明教程 -- VS环境配置 3.DuiLib入门简明教程 -- ...

  7. ASP.NET MVC Bundle使用 合并压缩

    2017-01-06 更新 在 BundleCollection 的构造函数中添加了 3种默认规则 public BundleCollection() { BundleCollection.AddDe ...

  8. canvas第一天

    第一次接触canvas,<canvas></canvas>是html5出现的新标签,IE9开始支持,像所有的dom对象一样它有自己本身的属性.方法和事件,其中就有绘图的方法,j ...

  9. JavaScript高级编程 (1) - javscript是什么

    <重温javascript>这是一系列 javascript 的学习笔记,部分内容摘自书本或者网络,我这里只是基于自己的理解进行了梳理整理. 一个完整的 javscript 实现是由以下3 ...

  10. Oracle_创建和管理表

    创建和管理表 常见的数据库对象 Oracle 数据库中的表 查询数据字典 命名规则 CREATE TABLE 语句 数据类型 使用子查询创建表 ALTER TABLE 语句 删除表 清空表 改变对象的 ...