Android雁翎刀之ImageView之异步下载

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229


雁翎刀

        《鹿鼎记》神龙教无根道人:许雪亭一对判官笔向洪教主背心连递两招,同时无根道人的雁翎刀也已砍向他腰间。

        今天我们学习如何利用Android平台“雁翎刀”ImageView来异步显示从网络下载的图片。像我们在浏览网页中的图片时,经常会遇到图片刷新的情景,尤其是在网络状况不给力的情况下。实质上对于这些图片的加载通常都是以异步方式实现的。下面给出该情景的案例:

1案例技术要点

(1)编写HTTP协议工具类HttpUtils,并提供如下两个方法:getInputStream():获取网络中图片的输入流。getBytes():获取网络中图片的字节数组。
(2)开启一个工作线程从网络上读取图片的字节数组,然后将其推送到Handler的消息队列当中。
(3)使用Handler类的handleMessage()方法接收此字节数组,并显示在对应的ImageView控件中。

2案例代码陈列

工程包目录

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.imageview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".ImageViewMainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest> 

strings.xml

<resources>
    <string name="app_name">ImageView从网络下载图片</string>
    <string name="download">下载图片</string>
</resources>

main.xml

<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     android:orientation="vertical">

     <ImageView
         android:id="@+id/imageView"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:src="@android:drawable/star_big_on"
         android:layout_gravity="center_horizontal" />
     <Button
        android:id="@+id/download_btn" 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/download" />

</LinearLayout>

HTTP请求服务工具类:HttpUtils.java

package com.android.imageview;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

/**
 * HTTP请求工具类
 * @author lynnli1229
 */
public class HttpUtils {
    // 网络上待下载图片的路径
    private static final String URL_PATH = "http://www.linuxidc.com/upload/2012_12/121218101020341.png";

    public static InputStream getInputStream() throws IOException {
        InputStream in = null;
        URL url = new URL(URL_PATH);
        if (url != null) {
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setConnectTimeout(3000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            if (conn.getResponseCode() == 200) {
                in = conn.getInputStream();
            }
        }
        return in;
    }

    public static byte[] getBytes() throws IOException {
        byte[] data = null;
        InputStream in = null;
        int len = 0;
        byte[] buffer = new byte[1024];
        // 此输出流不需要关闭,直接写入内存中
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            URL url = new URL(URL_PATH);
            if (url != null) {
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                // 设置HTTP连接超时为3s,防止页面出现“假死”现象
                conn.setConnectTimeout(3000);
                // 设置采用GET方式请求数据
                conn.setRequestMethod("GET");
                // 允许从服务端读取数据
                conn.setDoInput(true);
                if (conn.getResponseCode() == 200) { // 服务端响应成功返回码为200
                    in = conn.getInputStream();
                    while ((len = in.read(buffer)) != -1) {
                        out.write(buffer, 0, len);
                    }
                    data = out.toByteArray();
                }
            }
        } catch (IOException e) {
            throw new IOException();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return data;
    }
}

ImageViewMainActivity.java

package com.android.imageview;

import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

/**
 * ImageView案例四:从网络上获取图像显示到本地
 * ImageView是用于显示图片的控件,支持对图片进行放大、缩小和旋转等
 * @author lynnli1229
 */
public class ImageViewMainActivity extends Activity implements OnClickListener {

    private Button downloadButton;
    private ImageView imageView;
    // 设置下载图片的消息标示(当只有一个消息任务时,此标示可以不设置)
    private static final int DOWNLOAD_IMAGE = 0x12;
    private byte[] data;
    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            // 取出包含下载图片字节数据的消息并处理
            byte[] data = (byte[]) msg.obj;
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            imageView.setImageBitmap(bitmap);
        }
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        downloadButton = (Button) findViewById(R.id.download_btn);
        imageView = (ImageView) findViewById(R.id.imageView);
        downloadButton.setOnClickListener(this);
    }
    
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.download_btn:
            // 点击下载按钮开启一个工作线程来下载图片
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        data = HttpUtils.getBytes();
                    } catch (IOException e) {

                    }
                    // 将封装下载图像的字节数据的消息发送到消息队列中等候处理
                    handler.sendMessage(handler.obtainMessage(DOWNLOAD_IMAGE, data));
                }
            }).start();
            break;
        }
    }

}

3案例效果展示

 
posted @ 2013-05-29 16:54  Innosight  阅读(224)  评论(0编辑  收藏  举报