`
java2liwei
  • 浏览: 13943 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

教你如何更省流量刷空间,微博---Android之异步加载网络图片

 
阅读更多

      朋友你是否有过这样的经历,当你刷空间,刷微博的时候,有的时候那些图片加载要很长时间,有的却直接可以看到无需慢慢等待,尤其是那些你已经刷过的内容,即使你处于断网的状态下也能看到,往往这种客户体验相对而言比较好,但是有的时候我们清理了手机的一些垃圾后,就不一样了,我们还得从新刷出来,下面我就要说说这个原理了。

      这所有的实现都是通过异步加载产生的,原理就是在我们运行软件时,我们需要将一些图片显示出来,那这些图片要从哪里获取呢,我们可以通过以下的方式获取,先看一张流程图:



 

       首先我们先从map缓存中获取图片,map就是我们先前已经下载好的图片的集合,如果没有,我们查找图片文件,看是否有相应的文件,如果没有我们就开辟一个线程下载图片,等图片下载完成后,我们就将图片的url和图片放到map集合中。下一次再次刷新时,我们就直接从文件中读取已经存在的图片。到这里你应该知道如何更省流量得刷空间了吧,但是我们要实现这种功能额。下面我讲解一下核心代码:

       首先我们创建这样一个类LazyImageLoader,类里面有下面的方法

public Bitmap get(String url,ImageLoaderCallback callback)
	{
		
		Bitmap bitmap = null;
		//先看map集合众是否有这个url的图片
		if(imgManger.contains(url))
		{	
			//直接获取
			bitmap = imgManger.getFromCache(url);
			return bitmap;
		}
		
		else
		{
			callbackManager.put(url, callback);
			//开启线程下载
			startDownLoadTread(url);
		}
		//先返回一个默认的图片
		return getDefaultImag(R.drawable.user_head);
	}

 

      首先我们先从map中查看是否有这个url的图片,如果有直接返回,如果没有开启线程下载,同时先返回一个固定的默认图片接下来我们就要看一下ImgManger中关于图片文件获取的主要方法了:

      首先我们新建一个map如下Map<String, SoftReference<Bitmap>>imgCache;至于SoftReference是什么,我就不说了,在这里主要是提高运行速度。

      首先我们先从上面定义的map中查找,代码如下:

public Bitmap getFromMapCache(String url)
	{
		Bitmap bitmap = null;
		
		SoftReference<Bitmap> ref = null;
		
		synchronized (this)
		{
			ref = imgCache.get(url);
		}
		if(null != ref)
		{
			bitmap = ref.get();
			
		}
		return bitmap;
	}

 这里我们要注意防止线程同步的出现加关键词synchronized;

       如果没有,我们再从查找文件,看是否存在,这里我遇到了一个问题,同时我也明白了一件经常看到的事,显然我们要下载的图片的url是如http://www.xxx/xxx.png这样的格式,那我们将下载的文件命名保存呢?如果我们直接以url保存,那最后是读取和保存的,如果我们重命名,那么首先我们要怎样才能确定保存的是独一无二的呢,其次读取时又要按先前对文件命名的规则对URL解析然后再获取图片,这样一来将会影响读取的速度,那解决办法是有的,通过使用加密算法对url直接加密生成一个独一无二的摘要即可,在这里我直接通过Md5进行加密,到这里你应该明白有时候我们看到的文件的名字是23d4c0e84e1e642088d184807e56e324,115d7b4284479089001c7962b2b906b1之类的吧。下面我们继续写代码:

public Bitmap getFromFile(String url)
	{
		
		String fileName = this.getMd5(url);
		
		FileInputStream is=null;
		
		try
		{
			is=context.openFileInput(fileName);
			
			return BitmapFactory.decodeStream(is);
		} 
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
			return null;
		}
		finally
		{
			if(null != is)
			{
				try{is.close();}catch(Exception ex){};
			}
		}

    上面是直接从文件中查找图片,如果此时还没有,那么我们只有开启线程,通过线程来下载我们所需的图片,再将图片写到文件在写文件的时候文件名是也需要通过md5加密的。线程中主要的代码如下:

public Bitmap downloadImg(String urlStr) throws HttpException
	{
		
		try
		{
			URL url = new URL(urlStr);
			HttpURLConnection connection =(HttpURLConnection) url.openConnection();
			
			String fileName=writerToFile(urlStr,connection.getInputStream());
			
			return BitmapFactory.decodeFile(fileName);
			
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
		
		return null;
	}

 上面是通过http从网络中获取数据,其中的writerToFile方法如下:

public String  writerToFile(String fileName, InputStream is)
	{
		
		BufferedInputStream bis = null;
		
		BufferedOutputStream bos = null;
		
		try
		{
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(context.openFileOutput(MD5Utils.md5(fileName), Context.MODE_PRIVATE));
			
			byte[] buffer = new byte[1024];
			int length;
			
			while((length = bis.read(buffer)) != -1)
			{
				bos.write(buffer, 0, length);
			}
			
		} catch (Exception e)
		{
			
		}
		finally
		{
			
			try
			{
				if(null != bis)
				{
					bis.close();
				}
				
				if(null != bos)
					{
						bos.flush();
						bos.close();
					
					}
				
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
		
		
		return context.getFilesDir() + "/" + MD5Utils.md5(fileName);
		
	}

 主要是快速读写文件的操作,挺简单的,不懂直接百度,最后当我们的文件写好了,再通过回调的方法
将图片显示出来就行了。下面是我写的小项目的测试,效果还是挺好的,


异步加载的源码我放在下面,稍微改一下
可以直接用,直接调用类SimpleImageLoader 中的showImg(ImageView view,String url);方法即可。
 

分享到:
评论

相关推荐

    java开源包5

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包1

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包10

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    Java资源包01

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    JAVA上百实例源码以及开源项目源代码

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    JAVA上百实例源码以及开源项目

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java开源包11

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包2

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包3

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包6

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包4

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包8

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包7

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包9

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包101

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

Global site tag (gtag.js) - Google Analytics