当前位置: 代码迷 >> Android >> android之图片异步加载并缓存到当地
  详细解决方案

android之图片异步加载并缓存到当地

热度:54   发布时间:2016-05-01 12:03:03.0
android之图片异步加载并缓存到本地

?

在android项目中访问网络图片是非常普遍性的事情,如果我们每次请求都要访问网络来获取图片,会非常耗费流量,而且图片占用内存空间也比较大,图片过多且不释放的话很容易造成内存溢出。针对上面遇到的两个问题,首先耗费流量我们可以将图片第一次加载上面缓存到本地,以后如果本地有就直接从本地加载。图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略。今天首先介绍一下本地缓存图片。

?????????? 首先看一下异步加载缓存本地代码:

?

[html]?view plaincopy
  1. public?class?AsyncBitmapLoader????
  2. {????
  3. ????/**???
  4. ?????*?内存图片软引用缓冲???
  5. ?????*/????
  6. ????private?HashMap<String,?SoftReference<Bitmap>>?imageCache?=?null;????
  7. ????????
  8. ????public?AsyncBitmapLoader()????
  9. ????{????
  10. ????????imageCache?=?new?HashMap<String,?SoftReference<Bitmap>>();????
  11. ????}????
  12. ????????
  13. ????public?Bitmap?loadBitmap(final?ImageView?imageView,?final?String?imageURL,?final?ImageCallBack?imageCallBack)????
  14. ????{????
  15. ????????//在内存缓存中,则返回Bitmap对象????
  16. ????????if(imageCache.containsKey(imageURL))????
  17. ????????{????
  18. ????????????SoftReference<Bitmap>?reference?=?imageCache.get(imageURL);????
  19. ????????????Bitmap?bitmap?=?reference.get();????
  20. ????????????if(bitmap?!=?null)????
  21. ????????????{????
  22. ????????????????return?bitmap;????
  23. ????????????}????
  24. ????????}????
  25. ????????else????
  26. ????????{????
  27. ????????????/**???
  28. ?????????????*?加上一个对本地缓存的查找???
  29. ?????????????*/????
  30. ????????????String?bitmapName?=?imageURL.substring(imageURL.lastIndexOf("/")?+?1);????
  31. ????????????File?cacheDir?=?new?File("/mnt/sdcard/test/");????
  32. ????????????File[]?cacheFiles?=?cacheDir.listFiles();????
  33. ????????????int?i?=?0;????
  34. ????????????if(null!=cacheFiles){??
  35. ????????????for(;?i<cacheFiles.length;?i++)????
  36. ????????????{????
  37. ????????????????if(bitmapName.equals(cacheFiles[i].getName()))????
  38. ????????????????{????
  39. ????????????????????break;????
  40. ????????????????}????
  41. ????????????}????
  42. ????????????????
  43. ????????????if(i?<?cacheFiles.length)????
  44. ????????????{????
  45. ????????????????return?BitmapFactory.decodeFile("/mnt/sdcard/test/"?+?bitmapName);????
  46. ????????????}??
  47. ????????????}??
  48. ????????}????
  49. ????????????
  50. ????????final?Handler?handler?=?new?Handler()????
  51. ????????{????
  52. ????????????/*?(non-Javadoc)???
  53. [email protected]#handleMessage(android.os.Message)???
  54. ?????????????*/????
  55. [email protected]
  56. ????????????public?void?handleMessage(Message?msg)????
  57. ????????????{????
  58. ????????????????//?TODO?Auto-generated?method?stub????
  59. ????????????????imageCallBack.imageLoad(imageView,?(Bitmap)msg.obj);????
  60. ????????????}????
  61. ????????};????
  62. ????????????
  63. ????????//如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片????
  64. ????????new?Thread()????
  65. ????????{????
  66. ????????????/*?(non-Javadoc)???
  67. [email protected]#run()???
  68. ?????????????*/????
  69. [email protected]
  70. ????????????public?void?run()????
  71. ????????????{????
  72. ????????????????//?TODO?Auto-generated?method?stub????
  73. ????????????????InputStream?bitmapIs?=?HttpUtils.getStreamFromURL(imageURL);????
  74. ????????????????????
  75. ????????????????Bitmap?bitmap?=?BitmapFactory.decodeStream(bitmapIs);????
  76. ????????????????imageCache.put(imageURL,?new?SoftReference<Bitmap>(bitmap));????
  77. ????????????????Message?msg?=?handler.obtainMessage(0,?bitmap);????
  78. ????????????????handler.sendMessage(msg);????
  79. ????????????????????
  80. ????????????????File?dir?=?new?File("/mnt/sdcard/test/");????
  81. ????????????????if(!dir.exists())????
  82. ????????????????{????
  83. ????????????????????dir.mkdirs();????
  84. ????????????????}????
  85. ????????????????????
  86. ????????????????File?bitmapFile?=?new?File("/mnt/sdcard/test/"?+?????
  87. ????????????????????????imageURL.substring(imageURL.lastIndexOf("/")?+?1));????
  88. ????????????????if(!bitmapFile.exists())????
  89. ????????????????{????
  90. ????????????????????try????
  91. ????????????????????{????
  92. ????????????????????????bitmapFile.createNewFile();????
  93. ????????????????????}????
  94. ????????????????????catch?(IOException?e)????
  95. ????????????????????{????
  96. ????????????????????????//?TODO?Auto-generated?catch?block????
  97. ????????????????????????e.printStackTrace();????
  98. ????????????????????}????
  99. ????????????????}????
  100. ????????????????FileOutputStream?fos;????
  101. ????????????????try????
  102. ????????????????{????
  103. ????????????????????fos?=?new?FileOutputStream(bitmapFile);????
  104. ????????????????????bitmap.compress(Bitmap.CompressFormat.PNG,?????
  105. ????????????????????????????100,?fos);????
  106. ????????????????????fos.close();????
  107. ????????????????}????
  108. ????????????????catch?(FileNotFoundException?e)????
  109. ????????????????{????
  110. ????????????????????//?TODO?Auto-generated?catch?block????
  111. ????????????????????e.printStackTrace();????
  112. ????????????????}????
  113. ????????????????catch?(IOException?e)????
  114. ????????????????{????
  115. ????????????????????//?TODO?Auto-generated?catch?block????
  116. ????????????????????e.printStackTrace();????
  117. ????????????????}????
  118. ????????????}????
  119. ????????}.start();????
  120. ????????????
  121. ????????return?null;????
  122. ????}????
  123. ??
  124. ????public?interface?ImageCallBack????
  125. ????{????
  126. ????????public?void?imageLoad(ImageView?imageView,?Bitmap?bitmap);????
  127. ????}????
  128. }??

???? 这是一个封装好的异步加载图片类,缓存了两份,一份是使用软引用缓存到内存中,一份是缓存到本地sd卡,如果内存中没有,则从本地查找,如果本地没有则从网络获取图片。

?

?

[html]?view plaincopy
  1. public?class?HttpUtils?{??
  2. ??
  3. ????public?static?InputStream?getStreamFromURL(String?imageURL)?{??
  4. ????????InputStream?in=null;??
  5. ????????try?{??
  6. ????????????URL?url=new?URL(imageURL);??
  7. ????????????HttpURLConnection?connection=(HttpURLConnection)?url.openConnection();??
  8. ????????????in=connection.getInputStream();??
  9. ??????????????
  10. ????????}?catch?(Exception?e)?{??
  11. ????????????//?TODO?Auto-generated?catch?block??
  12. ????????????e.printStackTrace();??
  13. ????????}??
  14. ????????return?in;??
  15. ??????????
  16. ????}??
  17. }??

??? 这是一个访问网络获取类。不细说了。

?

?? 下面看一下如何使用封装好的异步加载图片的类:

?

[html]?view plaincopy
  1. public?class?ImageCacheActivity?extends?Activity?{??
  2. ????/**?Called?when?the?activity?is?first?created.?*/??
  3. ????private?ListView?listview;??
  4. [email protected]
  5. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  6. ????????super.onCreate(savedInstanceState);??
  7. ????????setContentView(R.layout.main);??
  8. ??????????
  9. ????????listview=(ListView)?findViewById(R.id.listView_list);??
  10. ????????MyAdapter?adapter=new?MyAdapter();??
  11. ????????listview.setAdapter(adapter);??
  12. ????}??
  13. ??????
  14. ????private?class?MyAdapter?extends?BaseAdapter{??
  15. ??
  16. ????????private?AsyncBitmapLoader?asyncBitmapLoader;??
  17. ????????public?MyAdapter(){??
  18. ????????????asyncBitmapLoader=new?AsyncBitmapLoader();??
  19. ????????}??
  20. [email protected]
  21. ????????public?int?getCount()?{??
  22. ????????????//?TODO?Auto-generated?method?stub??
  23. ????????????return?10;??
  24. ????????}??
  25. ??
  26. [email protected]
  27. ????????public?Object?getItem(int?position)?{??
  28. ????????????//?TODO?Auto-generated?method?stub??
  29. ????????????return?null;??
  30. ????????}??
  31. ??
  32. [email protected]
  33. ????????public?long?getItemId(int?position)?{??
  34. ????????????//?TODO?Auto-generated?method?stub??
  35. ????????????return?0;??
  36. ????????}??
  37. ??
  38. [email protected]
  39. ????????public?View?getView(int?position,?View?convertView,?ViewGroup?parent)?{??
  40. ????????????//?TODO?Auto-generated?method?stub??
  41. ????????????if(convertView==null){??
  42. ????????????????convertView=LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_item,?null);??
  43. ????????????}??
  44. ????????????ImageView?image=(ImageView)?convertView.findViewById(R.id.addexam_list_icon);??
  45. ????????????String?imageURL="http://s.ata.net.cn/4f98db46908987a21a000003/logo/2012/04/114_80aaf295c083d07a496743699aac3193.png";??
  46. ????????????Bitmap?bitmap=asyncBitmapLoader.loadBitmap(image,?imageURL,?new?ImageCallBack()?{??
  47. ??????????????????
  48. [email protected]
  49. ????????????????public?void?imageLoad(ImageView?imageView,?Bitmap?bitmap)?{??
  50. ????????????????????//?TODO?Auto-generated?method?stub??
  51. ????????????????????imageView.setImageBitmap(bitmap);??
  52. ????????????????}??
  53. ????????????});??
  54. ?????????????if(bitmap?==?null)????
  55. ????????????????{????
  56. ???????????????????image.setImageResource(R.drawable.ic_launcher);????
  57. ????????????????}????
  58. ????????????????else????
  59. ????????????????{????
  60. ????????????????????image.setImageBitmap(bitmap);????
  61. ????????????????}????
  62. ????????????????????
  63. ????????????return?convertView;??
  64. ????????}??
  65. ??????????
  66. ????}??
  67. }??

这样就完成了,网络获取不到bitmap则显示默认图片。

?

?

这是一种很实用的方法,大家自己试试吧!

  相关解决方案