Android HttpURLConnection 加载网络图片

来源:互联网 发布:网络短剧 搞笑 编辑:程序博客网 时间:2024/05/22 10:54

项目简介:

项目名称为网络图片查看器。

详细介绍:

如下图所示,点击按钮后显示一张图片,这张图片是从网络上下载的。
这里写图片描述
并且该图片可以上下滑动(因为这张图长度超过了屏幕)。如果再次点击按钮,就会吐司弹出一个信息,告诉这张图片在缓存中,是直接从缓存中加载的,并非是从网络上再次下载的。所以,这个应用完成的是两个操作,第一个是从网络上下载图片并显示,第二个是缓存图片。

该应用涉及到的知识有:

  • 1.Handler的使用
  • 2.HttpURLConnection的使用
      1)获取HttpURLConnection对象
      2)设置属性
      3)连接,并判断响应码
      4)读取数据

注意:

  • 1.图片过大可能导致内存溢出,所以,加载一张小的图片,或者自己写算法。如何加载大图请参考
  • 2.涉及到访问网络,要加上权限。

步骤:

1.准备工作

既然要从网络上加载图片,首先肯定要有一个网络图片咯。这里自己新建一个Dynamic Web Project

这里写图片描述

Next

这里写图片描述

Next–》Next

这里写图片描述

finish完成,在WebRoot目录放一张图片,如下所示:

这里写图片描述

完成后,配置好eclipse的tomcat服务器,然后部署上,在浏览器下输入http://http://10.12.22.173:8080/Jweb/a1.jpg:8080/Jweb/a1.jpg测试一下是否可以使用,其中把10.12.22.173换成自己的IP地址,但是不要用localhost代替,因为Android系统与window不是同一个系统中,一旦应用运行在模拟器中,localhost指的就是android设备了,而不再是电脑。

2.创建Android应用

编写activity_main.xml布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="hhh.exercise.j_a_netimgviewer.MainActivity" >    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="seeImg"        android:text="你懂得,点击看图"        android:textColor="#fff200"        android:textSize="30sp" />    <ScrollView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:fillViewport="true" >        <!-- android:adjustViewBounds="true"这条语句可以消除图片子啊屏幕中显示时出现的上下有白边的问题 ,但是可能会使图片失真 -->        <ImageView            android:id="@+id/iv"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:adjustViewBounds="true" />    </ScrollView></LinearLayout>

这里的布局文件十分简单,就一个按钮,一个ImageView。ScrollView可以不加,但是如果图片长度大于屏幕宽度,就没办法往下滑动显示了。

3.Activity

编写MainActivity代码:

import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity {    private ImageView iv;    // 创建Handler对象,该对象的作用是更新UI    Handler handler = new Handler() {        // 当消息队列中有消息的时候,消息轮训器(Looper)会取出消息,并调用handleMessage()方法更新UI        @Override        public void handleMessage(Message msg) {            if (msg.what == 0) {                // 连接请求失败,吐司给出提示信息                Toast.makeText(MainActivity.this, "连接失败", 0).show();            } else if (msg.what == 1) {                // 获取信息成功,把信息现在在屏幕上                Bitmap bm = (Bitmap) msg.obj;                iv.setImageBitmap(bm);            } else if (msg.what == 2) {                // 抛出错误,给出提示信息                Toast.makeText(MainActivity.this, "连接过程中出错", 0).show();            } else {                Toast.makeText(MainActivity.this, "未知错误", 0).show();            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        iv = (ImageView) MainActivity.this.findViewById(R.id.iv);    }    public void seeImg(View view) {        // 点击按钮后开始下载图片        // 1、首先要确定下载的网址(可以自己新建一个动态Web,在里面放上一张图片)        // 注意:该文件不能太大,否则容易造成Android的内存溢出        final String path = "http://10.12.22.173:8080/Jweb/a1.jpg";        String filename = getFileName(path);        final File file = new File(getCacheDir().getPath(), filename);        // 判断缓存中是否有文件,如果有文件就直接读取缓存中的文件        if (file.exists()) {            Log.i("test", "文件存在");            Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());            // 此时代码执行在线程是UI线程,可以直接更新UI            iv.setImageBitmap(bm);        } else {            // 创建子线程            Thread thread = new Thread() {                @Override                public void run() {                    try {                        // 2、把网址封装成一个URL对象                        URL url = new URL(path);                        // 3.获取客户端和服务器的连接对象,此时客户端和服务器并没有连接                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();                        // 4、对连接对象进行初始化操作                        // 设置请求方式、连接超时,读取超时等                        conn.setReadTimeout(5000);                        conn.setConnectTimeout(5000);                        conn.setRequestMethod("GET");                        // 5、发送请求,与服务器建立连接(也可以不写,请求状态码是系统实际上会自动调用该方法)                        conn.connect();                        // 6、读取流中的数据                        // 获取响应码,判断请求是否成功,如果返回200,说明请求成功                        if (conn.getResponseCode() == 200) {                            // 连接成功,获取服务器中的流,流里的数据就是客户端请求的数据                            InputStream isInputStream = conn.getInputStream();                            // 读取流中的数据,把数据写到本地文件,缓存起来                            FileOutputStream os = new FileOutputStream(file);                            int len = 0;                            byte[] buffer = new byte[1024];                            while ((len = isInputStream.read(buffer)) != -1) {                                os.write(buffer, 0, len);                                os.flush();                            }                            // 此时输入流中已经没有数据了,流中的数据已经读取完毕,可以关闭了。输出流也要关闭                            os.close();                            isInputStream.close();                            // 通过缓存文件创建位图对象.                            // 如果没有文件路径,可以通过流来创建文件,即decodeStream()方法                            Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());                            // 获取Message对象                            Message msg = handler.obtainMessage();                            // 设置标示                            msg.what = 1;                            // 把数据存储到Message对象中(如果数据不止一个,可以使用数组、List传出)                            msg.obj = bm;                            // 把Message发送至主线程                            handler.sendMessage(msg);                        } else {                            // 请求失败,发送失败信息给主线程                            handler.sendEmptyMessage(0);                        }                    } catch (Exception e) {                        Log.i("test", "出错啦");                        handler.sendEmptyMessage(2);                        e.printStackTrace();                    }                }            };            thread.start();        }    }    // 截取传入字符串的最后几个字符作为文件名    public String getFileName(String path) {        // 获取最后一个/的索引位置        int index = path.lastIndexOf("/");        // 返回最后一个/后面的字符串        return path.substring(index + 1);    }}

4.清单文件

设计到访问网络,需要添加权限

<uses-permission android:name="android.permission.INTERNET"/>

整个应用全部完成,但是可以看到从网络加载图片代码还是挺过的。所以,有一个封装好的开源项目SmartView,十分好用。具体用法如下:

  • 1.下载文件后,解压,直接把src目录下的所以复制粘贴到自己的项目中(这个开源给的是源码包,良心啊)
  • 1.在布局文件中定义SmartView,这个控件的使用与ImageView十分相似
  • 2.在Activity或者其他Java类中,直接使用setImageUrl方法,传入一个Url,图片就可以加载出来了。而且,可以加载大图片,十分好用。
    SmartView下载地址,点击跳转
0 0
原创粉丝点击