广

android开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    android异步加载图片并缓存到本地实现方法

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

    publicclassAsyncBitmapLoader
    {
    /**
    *内存图片软引用缓冲
    */
    privateHashMap<String,SoftReference<Bitmap>>imageCache=null;
    publicAsyncBitmapLoader()
    {
    imageCache=newHashMap<String,SoftReference<Bitmap>>();
    }
    publicBitmaploadBitmap(finalImageViewimageView,finalStringimageURL,finalImageCallBackimageCallBack)
    {
    //在内存缓存中,则返回Bitmap对象
    if(imageCache.containsKey(imageURL))
    {
    SoftReference<Bitmap>reference=imageCache.get(imageURL);
    Bitmapbitmap=reference.get();
    if(bitmap!=null)
    {
    returnbitmap;
    }
    }
    else
    {
    /**
    *加上一个对本地缓存的查找
    */
    StringbitmapName=imageURL.substring(imageURL.lastIndexOf("/")+1);
    FilecacheDir=newFile("/mnt/sdcard/test/");
    File[]cacheFiles=cacheDir.listFiles();
    inti=0;
    if(null!=cacheFiles){
    for(;i<cacheFiles.length;i++)
    {
    if(bitmapName.equals(cacheFiles[i].getName()))
    {
    break;
    }
    }
    if(i<cacheFiles.length)
    {
    returnBitmapFactory.decodeFile("/mnt/sdcard/test/"+bitmapName);
    }
    }
    }
    finalHandlerhandler=newHandler()
    {
    /*(non-Javadoc)
    *@seeandroid.os.Handler#handleMessage(android.os.Message)
    */
    @Override
    publicvoidhandleMessage(Messagemsg)
    {
    //TODOAuto-generatedmethodstub
    imageCallBack.imageLoad(imageView,(Bitmap)msg.obj);
    }
    };
    //如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片
    newThread()
    {
    /*(non-Javadoc)
    *@seejava.lang.Thread#run()
    */
    @Override
    publicvoidrun()
    {
    //TODOAuto-generatedmethodstub
    InputStreambitmapIs=HttpUtils.getStreamFromURL(imageURL);
    Bitmapbitmap=BitmapFactory.decodeStream(bitmapIs);
    imageCache.put(imageURL,newSoftReference<Bitmap>(bitmap));
    Messagemsg=handler.obtainMessage(0,bitmap);
    handler.sendMessage(msg);
    Filedir=newFile("/mnt/sdcard/test/");
    if(!dir.exists())
    {
    dir.mkdirs();
    }
    FilebitmapFile=newFile("/mnt/sdcard/test/"+
    imageURL.substring(imageURL.lastIndexOf("/")+1));
    if(!bitmapFile.exists())
    {
    try
    {
    bitmapFile.createNewFile();
    }
    catch(IOExceptione)
    {
    //TODOAuto-generatedcatchblock
    e.printStackTrace();
    }
    }
    FileOutputStreamfos;
    try
    {
    fos=newFileOutputStream(bitmapFile);
    bitmap.compress(Bitmap.CompressFormat.PNG,
    100,fos);
    fos.close();
    }
    catch(FileNotFoundExceptione)
    {
    //TODOAuto-generatedcatchblock
    e.printStackTrace();
    }
    catch(IOExceptione)
    {
    //TODOAuto-generatedcatchblock
    e.printStackTrace();
    }
    }
    }.start();
    returnnull;
    }
    publicinterfaceImageCallBack
    {
    publicvoidimageLoad(ImageViewimageView,Bitmapbitmap);
    }
    }

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

    publicclassHttpUtils{
    publicstaticInputStreamgetStreamFromURL(StringimageURL){
    InputStreamin=null;
    try{
    URLurl=newURL(imageURL);
    HttpURLConnectionconnection=(HttpURLConnection)url.openConnection();
    in=connection.getInputStream();

    }catch(Exceptione){
    //TODOAuto-generatedcatchblock
    e.printStackTrace();
    }
    returnin;

    }
    }

    这是一个访问网络获取类。不细说了。
    下面看一下如何使用封装好的异步加载图片的类:
    代码如下:

    publicclassImageCacheActivityextendsActivity{
    /**Calledwhentheactivityisfirstcreated.*/
    privateListViewlistview;
    @Override
    publicvoidonCreate(BundlesavedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    listview=(ListView)findViewById(R.id.listView_list);
    MyAdapteradapter=newMyAdapter();
    listview.setAdapter(adapter);
    }
    privateclassMyAdapterextendsBaseAdapter{
    privateAsyncBitmapLoaderasyncBitmapLoader;
    publicMyAdapter(){
    asyncBitmapLoader=newAsyncBitmapLoader();
    }
    @Override
    publicintgetCount(){
    //TODOAuto-generatedmethodstub
    return10;
    }
    @Override
    publicObjectgetItem(intposition){
    //TODOAuto-generatedmethodstub
    returnnull;
    }
    @Override
    publiclonggetItemId(intposition){
    //TODOAuto-generatedmethodstub
    return0;
    }
    @Override
    publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
    //TODOAuto-generatedmethodstub
    if(convertView==null){
    convertView=LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_item,null);
    }
    ImageViewimage=(ImageView)convertView.findViewById(R.id.addexam_list_icon);
    StringimageURL="http://s.ata.net.cn/4f98db46908987a21a000003/logo/2012/04/114_80aaf295c083d07a496743699aac3193.png";
    Bitmapbitmap=asyncBitmapLoader.loadBitmap(image,imageURL,newImageCallBack(){

    @Override
    publicvoidimageLoad(ImageViewimageView,Bitmapbitmap){
    //TODOAuto-generatedmethodstub
    imageView.setImageBitmap(bitmap);
    }
    });
    if(bitmap==null)
    {
    image.setImageResource(R.drawable.ic_launcher);
    }
    else
    {
    image.setImageBitmap(bitmap);
    }

    returnconvertView;
    }

    }
    }

    这样就完成了,网络获取不到bitmap则显示默认图片。
     
    这是一种很实用的方法,大家自己试试吧!

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告