网络图片查看器

  • 确定图片的网址
  • 发送http请求

    URL url = new URL(address);
    //获取连接对象,并没有建立连接
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    //设置连接和读取超时
    conn.setConnectTimeout(5000);
    conn.setReadTimeout(5000);
    //设置请求方法,注意必须大写
    conn.setRequestMethod("GET");
    //建立连接,发送get请求
    //conn.connect();
    //建立连接,然后获取响应吗,200说明请求成功
    conn.getResponseCode();
  • 服务器的图片是以流的形式返回给浏览器的

    //拿到服务器返回的输入流
    InputStream is = conn.getInputStream();
    //把流里的数据读取出来,并构造成图片
    Bitmap bm = BitmapFactory.decodeStream(is);
  • 把图片设置为ImageView的显示内容

    ImageView iv = (ImageView) findViewById(R.id.iv);
    iv.setImageBitmap(bm);
  • 添加权限
  • eg:
 ublic class MainActivity extends Activity {

     @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} public void click(View v){
//请求网址获取图片
//1.确定网址
String path = "http://10.16.17.138:8080/DT.png";
try {
//2.获取url对象
URL url = new URL(path);
//3获取连接对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//4.初始化连接对象
//设置请求的方法
conn.setRequestMethod("GET");
//读取超时/连接超时
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000); //5.和服务器建立连接
conn.connect(); if (conn.getResponseCode() == 200) {
//6.拿到服务器返回的流,客户端请求的数据,就保存在流中
InputStream is = conn.getInputStream(); //7.从流里读取数据,构成一个图片对象
Bitmap bm = BitmapFactory.decodeStream(is);
ImageView iv = (ImageView) findViewById(R.id.iv); //8.把图片设置进imageView
iv.setImageBitmap(bm);
}
else{
Toast.makeText(this, "请求失败", 0).show();
}
} catch (Exception e) {
e.printStackTrace();
}
} }

注:上面代码,只能2.3的虚拟机上运行,若在4.0上运行会报主线程网络异常:android.os.NetworkOnMainThreadException

阻塞一般为:

//5.和服务器建立连接
conn.connect();
//6.拿到服务器返回的流,客户端请求的数据,就保存在流中
InputStream is = conn.getInputStream();
 

主线程不能被阻塞

  • 在Android中,主线程被阻塞会导致应用不能刷新ui界面,不能响应用户操作(home键是有效的),用户体验将非常差
  • 主线程阻塞时间过长,系统会抛出ANR异常
  • ANR:Application Not Response;应用无响应
  • 任何耗时操作都不可以写在主线程
  • 因为网络交互属于耗时操作,如果网速很慢,代码会阻塞,所以网络交互的代码不能运行在主线程

只有主线程能刷新ui

  • 刷新ui的代码只能运行在主线程,运行在子线程是没有任何效果的

    • 否则会提示出问题:
  • 如果需要在子线程中刷新ui,使用消息队列机制

    //消息队列
    Handler handler = new Handler(){
    //主线程中有一个消息轮询器looper,不断检测消息队列中是否有新消息,如果发现有新消息,自动调用此方法,注意此方法是在主线程中运行的
    public void handleMessage(android.os.Message msg) { }
    };
     
    
    

    消息队列

    • Looper一旦发现Message Queue中有消息,就会把消息取出,然后把消息扔给Handler对象,Handler会调用自己的handleMessage方法来处理这条消息
    • handleMessage方法运行在主线程
    • 其实就是说只要消息队列中有消息,就会触发主线程去执行handleMessage方法
    • 更直白的说,只要子线程往消息队列发消息,就会触发主线程去执行handleMessage方法
    • 主线程创建时,消息队列和轮询器对象就会被创建,但是消息处理器对象,需要使用时,自行创建
  • 在子线程中往消息队列里发消息
     
    //创建消息对象
    Message msg = new Message();
    //消息的obj属性可以赋值任何对象,通过这个属性可以携带数据
    msg.obj = bm;
    //what属性相当于一个标签,用于区分出不同的消息,从而运行不能的代码
    msg.what = 1;
    //发送消息
    handler.sendMessage(msg);
  • 通过switch语句区分不同的消息

    public void handleMessage(android.os.Message msg) {
    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;
    }
    }

加入缓存图片的功能

  • 把服务器返回的流里的数据读取出来,然后通过文件输入流写至本地文件

    //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());
  • 每次发送请求前检测一下在缓存中是否存在同名图片,如果存在,则读取缓存

获取开源代码的网站

  • code.google.com
  • github.com
  • 在github搜索smart-image-view
  • 下载开源项目smart-image-view
  • 使用自定义组件时,标签名字要写包名:

    <com.loopj.android.image.SmartImageView/>
  • SmartImageView的使用:

    SmartImageView siv = (SmartImageView) findViewById(R.id.siv);
    siv.setImageUrl("http://192.168.1.102:8080/dd.jpg");

Html源文件查看器

  • 发送GET请求

    URL url = new URL(path);
    //获取连接对象
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    //设置连接属性
    conn.setRequestMethod("GET");
    conn.setConnectTimeout(5000);
    conn.setReadTimeout(5000);
    //建立连接,获取响应吗
    if(conn.getResponseCode() == 200){ }
  • 获取服务器返回的流,从流中把html源码读取出来

    byte[] b = new byte[1024];
    int len = 0;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    while((len = is.read(b)) != -1){
    //把读到的字节先写入字节数组输出流中存起来
    bos.write(b, 0, len);
    }
    //把字节数组输出流中的内容转换成字符串
    //默认使用utf-8
    text = new String(bos.toByteArray());

乱码的处理

  • 乱码的出现是因为服务器和客户端码表不一致导致

    //手动指定码表
    text = new String(bos.toByteArray(), "gb2312");

提交数据

GET方式提交数据

  • get方式提交的数据是直接拼接在url的末尾

    final String path = "http://192.168.1.104/Web/servlet/CheckLogin?name=" + name + "&pass=" + pass;
  • 发送get请求,代码和之前一样

    URL url = new URL(path);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setReadTimeout(5000);
    conn.setConnectTimeout(5000);
    if(conn.getResponseCode() == 200){ }
  • 浏览器在发送请求携带数据时会对数据进行URL编码,我们写代码时也需要为中文进行URL编码

    String path = "http://192.168.1.104/Web/servlet/CheckLogin?name=" + URLEncoder.encode(name) + "&pass=" + pass;

POST方式提交数据

  • post提交数据是用流写给服务器的
  • 协议头中多了两个属性

    • Content-Type: application/x-www-form-urlencoded,描述提交的数据的mimetype
    • Content-Length: 32,描述提交的数据的长度

      //给请求头添加post多出来的两个属性
      String data = "name=" + URLEncoder.encode(name) + "&pass=" + pass;
      conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
      conn.setRequestProperty("Content-Length", data.length() + "");
  • 设置允许打开post请求的流

    conn.setDoOutput(true);
  • 获取连接对象的输出流,往流里写要提交给服务器的数据

    OutputStream os = conn.getOutputStream();
    os.write(data.getBytes());

Android应用开发基础之四:网络编程(一)的更多相关文章

  1. Objective-C ,ios,iphone开发基础:http网络编程

    - (IBAction)loadData:(id)sender { NSURL* url = [NSURL URLWithString:@"http://162.105.65.251:808 ...

  2. 用Netty开发中间件:网络编程基础

    用Netty开发中间件:网络编程基础 <Netty权威指南>在网上的评价不是很高,尤其是第一版,第二版能稍好些?入手后快速翻看了大半本,不免还是想对<Netty权威指南(第二版)&g ...

  3. 黑马程序员:Java基础总结----网络编程

    黑马程序员:Java基础总结 网络编程   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 网络编程 网络通讯要素 . IP地址 . 网络中设备的标识 . 不易记忆,可用 ...

  4. GO学习-(19) Go语言基础之网络编程

    Go语言基础之网络编程 现在我们几乎每天都在使用互联网,我们前面已经学习了如何编写Go语言程序,但是如何才能让我们的程序通过网络互相通信呢?本章我们就一起来学习下Go语言中的网络编程. 关于网络编程其 ...

  5. Android应用开发基础篇(1)-----Button

    Android应用开发基础篇(1)-----Button   一.概述        Button,顾名思义就是按钮的意思,它主要的功能是响应用户按下按钮时的动作. 二.应用      新建一个工程, ...

  6. python渗透测试入门——基础的网络编程工具

    <Python黑帽子--黑客与渗透测试编程之道学习>这本书是我在学习安全的过程中发现的在我看来十分优秀的一本书,业内也拥有很高的评价,所以在这里将自己的学习内容分享出来. 1.基础的网络编 ...

  7. python基础(29):网络编程(软件开发架构、网络基础、套接字初使用)

    1. 软件开发架构 我们了解的程序之间通讯的应用可分为两种: 第一种是应用类:qq.微信.百度网盘.腾讯视频这一类是属于需要安装的桌面应用. 第二种是web类:比如百度.知乎.博客园等使用浏览器访问就 ...

  8. 黑马程序员_Java基础:网络编程总结

    ------- android培训.java培训.期待与您交流! ---------- Java语言是在网络环境下诞生的,它是第一个完全融入网络的语言,虽然不能说它是对支持网络编程做得最好的语言,但是 ...

  9. Android应用开发基础篇(12)-----Socket通信

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378669.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌 ...

随机推荐

  1. node.js中log4js的使用

    以前用过forever进程守护的日志记录到指定文件,但是只能保存到一个文件中不能分片,这样到只日志文件越来越大, forever start -s -l ./forever.log app.js -l ...

  2. url rewrite

    http://www.microsoft.com/taiwan/technet/iis/expand/URLRewrite.aspx http://www.iis.net/learn/extensio ...

  3. win平台,apache通过web访问svn

    上个月用php写一个在线打包lua变成luac,碰到个权限问题.pysvn无法更新.网上搜了好半天都找不到解决方法.最好还是自己解决了. 解决方法也很简单,找到aphache服务,提权限就行了.lin ...

  4. 十家国内知名的EDM服务提供商

    国内的EDM服务商多若繁星.下面博主为大家介绍十家国内知名的EDM服务提供商. 一.Webpower 威勃庞尔. 官方网站是:www.webpower.asia.作为全球领先的邮件营销解决方案提供商, ...

  5. CDN 和 DNS

    原文地址:http://www.cnblogs.com/xitang/p/3575255.html 相信有很多的朋友会被这几个名词绕的有些头大,很多朋友觉得智能DNS跟双线加速.CDN加速是类似的技术 ...

  6. Qt4.8.6 Embedded Linux 的编译与移植

    最近买了个飞凌ok6410 的开发板,于是在其中搭建qt4.8.6运行环境.费了两三天时间,主要还是对Linux系统的生疏,在一些问题上徘徊很久,在这里做一些过程笔记.烧写ARM-Linux系统,根据 ...

  7. 解决 Tomcat 无法绑定 80 端口的问题,以及 Tomcat 配置虚拟目录、二级域名等

    问题 今天安装完 Tomcat,安装时把 Tomcat 默认的 HTTP/1.1 Connector Port 从 8080 改为了 7080,启动 Tomcat,在浏览器中输入 Http://loc ...

  8. css3,background-clip/background-origin的使用场景,通俗讲解

    先不说background-clip/background-origin的用法,我们先来聊聊css背景方面的知识. <!DOCTYPE html> <html lang=" ...

  9. Could not load file or assembly 'System.Core, Version=2.0.5.0 和autofac冲突的问题

    在部署到iis的时候会出现这个状况. 解决:下载安装这个补丁 http://support.microsoft.com/kb/2468871 http://www.microsoft.com/zh-c ...

  10. 编写高质量JS代码的68个有效方法(五)

    No.21.使用apply方法通过不同数量的参数调用函数 Tips: 使用apply方法自定一个可计算的参数数组来调用可变参数的函数 使用apply方法的第一个参数给可变参数的方法提供一个接收者 // ...