Android中用URL模拟一个简单的图片加载器

首先,需要添加权限。

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

整体代码如下:

package com.tarena.viewer;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
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.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * 网络图片查看器,需要添加Internet权限
 * @author chenchi
 *
 */
public class MainActivity extends Activity implements OnClickListener {

    Handler handler = new Handler(){
        //处理消息的时候我们需要区分这是成功的消息还是失败的消息
        //此方法在主线程中调用,可以用来刷新UI
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case 1:
                ImageView imageView = (ImageView) findViewById(R.id.image_view);
                imageView.setImageBitmap((Bitmap) msg.obj);
                break;
            case 2:
                Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show();
                break;
            }
            
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_download = (Button) findViewById(R.id.btn_download);
        btn_download.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Thread thread = new Thread(new Runnable() {
            
            @Override
            public void run() {
                //下载图片
                //1.确定网址
                String path = "http://192.168.31.225:8088/user.png";
                try {
                    //2.把网址封装成一个URL对象
                    URL url = new URL(path);
                    //3.获取客户端和服务器的连接对象,此时还没有建立连接
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    //4.对连接对象进行初始化
                    //设置请求方法,注意大写
                    conn.setRequestMethod("GET");
                    //设置连接超时
                    conn.setConnectTimeout(10000);
                    //设置读取超时
                    conn.setReadTimeout(10000);
                    //5.发送请求,与服务器建立连接
                    conn.connect();
                    //如果响应码为200,说明请求成功
                    if(conn.getResponseCode() == 200){
                        //获取服务器响应头中的流,流里的数据就是客户端啊请求的数据
                        InputStream is = conn.getInputStream();
                        //读取出流里面的数据,并构造成位图对象
                        Bitmap bm = BitmapFactory.decodeStream(is);
                        
                        /*
                         * 这两行代码为什么注释,是因为运行也没有结果的
                         * 因为只有主线程才能刷新UI操作,子线程是不可以的
                         */
//                        ImageView imageView = (ImageView) findViewById(R.id.image_view);
//                        imageView.setImageBitmap(bm);
                        
                        //把消息返送到主线程的消息队列
                        Message msg = new Message();
                        //消息对象可以携带数据
                        msg.obj = bm;
                        msg.what = 1; //成功加载消息,返回1
                        handler.sendMessage(msg);
                    }else{
                        Message msg = handler.obtainMessage();//这样获取message是在池中获取,减少内存负荷
                        msg.what = 2;//失败加载消息,返回0
                        handler.sendMessage(msg);
                    }
                        
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        
        thread.start();
    }


}

 还可以继续加上缓存的功能。

package com.tarena.viewer;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.R.integer;
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.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * 网络图片查看器,需要添加Internet权限
 * @author chenchi
 *
 */
public class MainActivity extends Activity implements OnClickListener {
    
    private String getFilesName(String path) {
        int index = path.lastIndexOf("/");
        return path.substring(index + 1);
    }

    Handler handler = new Handler(){
        //处理消息的时候我们需要区分这是成功的消息还是失败的消息
        //此方法在主线程中调用,可以用来刷新UI
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case 1:
                ImageView imageView = (ImageView) findViewById(R.id.image_view);
                imageView.setImageBitmap((Bitmap) msg.obj);
                break;
            case 2:
                Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show();
                break;
            }
            
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_download = (Button) findViewById(R.id.btn_download);
        btn_download.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //下载图片
        //1.确定网址
        final String path = "http://192.168.31.225:8088/user.png";
        //读取数据库返回的流里的数据,把数据写到本地文件,缓存起来
        final File file = new File(getCacheDir(), getFilesName(path));
        //判断,缓存中是否存在该文件
        if(file.exists()){
            //如果缓存存在,从缓存中读取数据
            System.out.println("从缓存读取的");
            Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
            ImageView imageView = (ImageView) findViewById(R.id.image_view);
            imageView.setImageBitmap(bm);
            return;
        }
        System.out.println("从网络下载的");
        Thread thread = new Thread(new Runnable() {
            
            @Override
            public void run() {
                
                try {
                    //2.把网址封装成一个URL对象
                    URL url = new URL(path);
                    //3.获取客户端和服务器的连接对象,此时还没有建立连接
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    //4.对连接对象进行初始化
                    //设置请求方法,注意大写
                    conn.setRequestMethod("GET");
                    //设置连接超时
                    conn.setConnectTimeout(10000);
                    //设置读取超时
                    conn.setReadTimeout(10000);
                    //5.发送请求,与服务器建立连接
                    conn.connect();
                    //如果响应码为200,说明请求成功
                    if(conn.getResponseCode() == 200){
                        //获取服务器响应头中的流,流里的数据就是客户端啊请求的数据
                        InputStream is = conn.getInputStream();
                        
                        byte[] b = new byte[1024];
                        FileOutputStream fos = new FileOutputStream(file);
                        int len = -1;
                        while((len = is.read(b)) != -1){
                            fos.write(b, 0, len);
                        }
                        
                        //读取出流里面的数据,并构造成位图对象
                        //Bitmap bm = BitmapFactory.decodeStream(is);
                        Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
                        /*
                         * 这两行代码为什么注释,是因为运行也没有结果的
                         * 因为只有主线程才能刷新UI操作,子线程是不可以的
                         */
//                        ImageView imageView = (ImageView) findViewById(R.id.image_view);
//                        imageView.setImageBitmap(bm);
                        
                        //把消息返送到主线程的消息队列
                        Message msg = new Message();
                        //消息对象可以携带数据
                        msg.obj = bm;
                        msg.what = 1; //成功加载消息,返回1
                        handler.sendMessage(msg);
                    }else{
                        Message msg = handler.obtainMessage();//这样获取message是在池中获取,减少内存负荷
                        msg.what = 2;//失败加载消息,返回0
                        handler.sendMessage(msg);
                    }
                        
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        });
        
        thread.start();
    }


}
原文地址:https://www.cnblogs.com/DarrenChan/p/5462977.html