眼睛一闭一睁一天就过去了哼,眼睛一闭不睁一辈子就过去了哼。

好多应用,像我们公司的《乘友》还有其他的《飞鸽》《陌陌》《啪啪》这些,几乎每一款应用都需要加载网络图片,那ToYueXinShangWan,这是比须熟练掌握的一个点,下面开始学习:

一、最简单加载网络图片

从网络上取图片数据,显示在应用中,简单不赘述:

try {URL url = new URL(path); //path图片的网络地址HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();if(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){Bitmap bitmap = BitmapFactory.decodeStream(httpURLConnection.getInputStream());imageview.setImageBitmap(bitmap);//加载到ImageView上System.out.println("加载网络图片完成");}else{System.out.println("加载网络图片失败");}} catch (IOException e) {e.printStackTrace();}

二、轻量级异步加载图片

不会有人用第一种方法加载,连接网络和从网络取数据,花费部分时间,阻碍主线程,影响UI效果!

解决方案是:异步加载。先给ImageView设置一张图片,在异步任务中取数据,当从网络中取数据中和取数据失败时,就一直显示原来图片,当完成取数据时则再把新图片加载到ImageView上。

根据上面思路,就可以直接动手写了,为了便于代码复用,将加载图片写在一个工具类Utils中:

package com.lizhen.loadimage;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Message;public class Utils {public static void onLoadImage(final URL bitmapUrl,final OnLoadImageListener onLoadImageListener){final Handler handler = new Handler(){public void handleMessage(Message msg){onLoadImageListener.OnLoadImage((Bitmap) msg.obj, null);}};new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubURL imageUrl = bitmapUrl;try {HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();InputStream inputStream = conn.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);Message msg = new Message();msg.obj = bitmap;handler.sendMessage(msg);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();}public interface OnLoadImageListener{public void OnLoadImage(Bitmap bitmap,String bitmapPath);}}然后在需要加载图片的地方调用调用onLoadImage()方法即可,在接口OnLoadImageListener的回调方法OnLoadImage()中,如:

Utils.onLoadImage(url, new OnLoadImageListener() {@Overridepublic void OnLoadImage(Bitmap bitmap, String bitmapPath) {// TODO Auto-generated method stubif(bitmap!=null){imageview.setImageBitmap(bitmap);}}});wangluo jiazai zhong –>

读取完网络数据后,加载图片效果—->

三、第二种方法的弊端是,当有大量图片需要加载时,会启动很多线程,避免出现这种情况的方法是,定义线程个数,当线程数达到最多时,不再开启,直到有一个线程结束,再开启一个线程;这种做法相当于

引入ExecutorService接口,于是代码可以优化如下:

在主线程中加入:private ExecutorService executorService = Executors.newFixedThreadPool(5);

在相应位置修改代码如下:

executorService.submit(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubURL imageUrl = bitmapUrl;try {System.out.println(Thread.currentThread().getName() + "线程被调用了。");HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();InputStream inputStream = conn.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);Message msg = new Message();msg.obj = bitmap;handler.sendMessage(msg);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName() + "线程结束。");}});线程池大小为3,运行5个线程,我的输出结果为:

这里有关线程池的概念用法写在另一篇文章里!

四、关于方法二的改进,考虑到效率问题,可以引入缓存机制,把图片保留在本地,只需在线程run方法最后加上如下代码:

//缓存if(Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){System.out.println("存在sd卡");File cacheFile = new File(Environment.getExternalStorageDirectory()+"/cacheFile");System.out.println(cacheFile.getPath());if(!cacheFile.exists())cacheFile.mkdir();System.out.println(cacheFile.exists());File imageCache = new File(cacheFile.getPath()+"/netwrok.png");FileOutputStream fos = new FileOutputStream(imageCache);BufferedOutputStream bos = new BufferedOutputStream(fos);bitmap.compress(Bitmap.CompressFormat.PNG, 80, bos);bos.flush();bos.close();}另一种把图片缓存在内存中使用如下步骤:

1、主线程public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();

2、如果有缓存则读取缓存中数据,如果没有,则从网络获取数据;

每一个成功者都有一个开始。勇于开始,才能找到成功的路。

眼睛一闭一睁一天就过去了哼,眼睛一闭不睁一辈子就过去了哼。

相关文章:

你感兴趣的文章:

标签云: