网络图片查看器

  • 确定图片的网址
  • 发送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. 使用aspose.cell导出excel需要注意什么?

    1.如果导出的数据源是汇总出来的,最好方法是将数据源放到缓存里面,当基本数据源变化的时候,在改变数据2.使用模板导出EXCEL,这样很多样式可以在模板文件里面直接设置,例如:默认打开页签,让列头固定3 ...

  2. ODAC (V9.5.15) 学习笔记(二十一)数据复制

    用TVirtualTable在内存中缓存TOraQuery中的数据,主要应用场景是参照其他数据,需要将TOraQuery中的数据复制到TVirtualTable,由于没有类似于TClientDataS ...

  3. POJ 2234 Matches Game

    Matches Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7567   Accepted: 4327 Desc ...

  4. 用户Word写毕业论文时的文献引用方法

    经过网上搜索和自己实践,找到了一种不用第三方工具的文献管理方法 通过将文献定义的成书签的形式,插入到文献中,当文献编号发生变化时,只需进行更新域操作,就可实现文献编号的理新,下面介绍具体方法: 1.首 ...

  5. 获取全国市以及地理坐标,各大坐标系北斗,百度,WGS-84坐标系的转换,有图,有代码

    1 先上坐标取到的值: 获取到的坐标部分如下: '北京市':[116.39564503788,39.92998577808], '天津市':[117.21081309155,39.1439299033 ...

  6. ubuntu关闭自动更新、打开 ubuntu 的 apport 崩溃检测报告功能

    菜单栏点 系统 --->首选项 --->启动应用程序 --->更新提示 前面的钩打掉 关闭即可     =========== 打开 ubuntu 的 apport 崩溃检测报告功能 ...

  7. 组合模式及C++实现

    组合模式 组合模式,是为了解决整体和部分的一致对待的问题而产生的,要求这个整体与部分有一致的操作或行为.部分和整体都继承与一个公共的抽象类,这样,外部使用它们时是一致的,不用管是整体还是部分,使用一个 ...

  8. 快速开发~Rafy框架的初步认识

    当我们开始使用EF的同时,是不是就会更好的认识了其他的ORM框架,最近接触了Rafy的使用,感觉还是蛮有兴趣去学习的,虽然最初的我到现在看的并不深入,但是我个人感觉还是可以简单地做一些总结的啦,或许语 ...

  9. 代码演示 .NET 4.5 自带的 ReadonlyCollection 的使用

    代码如下: 1. using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  10. 整合ssh model $$_javassist_13 cannot be cast to javassist.util.proxy.Proxy

    经goole stackoverflow 发现是 javassit 包冲突 项目使用的是maven 检查依赖包