Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android中使用AsyncTask多次设置Imageview_Android - Fatal编程技术网

在Android中使用AsyncTask多次设置Imageview

在Android中使用AsyncTask多次设置Imageview,android,Android,我按照这个过程为我设置了一个简单的AsyncTask映像下载程序/加载程序。我从适配器的GetView内部调用下载函数。因此,每当我向上或向下滚动时,一旦视图离开屏幕,图像就会消失,只有当我滚动回该项目时,图像才会再次设置。如何停止此操作,并在下载/缓存完所有图像后进行设置。我不希望每次都重置ImageView 这是ImageManager: import java.io.File; import java.io.FileOutputStream; import java.net.URL; im

我按照这个过程为我设置了一个简单的AsyncTask映像下载程序/加载程序。我从适配器的GetView内部调用下载函数。因此,每当我向上或向下滚动时,一旦视图离开屏幕,图像就会消失,只有当我滚动回该项目时,图像才会再次设置。如何停止此操作,并在下载/缓存完所有图像后进行设置。我不希望每次都重置ImageView

这是ImageManager:

import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Stack;

import android.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;



public class ImageManager { 
      private HashMap<String, Bitmap> imageMap = new HashMap<String, Bitmap>(); 
      private File cacheDir;
      public Thread imageLoaderThread = new Thread() ;
      public ImageQueue imageQueue  = new ImageQueue();
      public ImageManager(Context context) {
        // Make background thread low priority, to avoid affecting UI performance
         imageLoaderThread.setPriority(Thread.NORM_PRIORITY-1);

        // Find the dir to save cached images
        String sdState = android.os.Environment.getExternalStorageState();
        if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
          File sdDir = android.os.Environment.getExternalStorageDirectory();    
          cacheDir = new File(sdDir,"data/codehenge");
        }
        else
          cacheDir = context.getCacheDir();

        if(!cacheDir.exists())
          cacheDir.mkdirs();
      }


      private void queueImage(String url, ImageView imageView) {
          // This ImageView might have been used for other images, so we clear 
          // the queue of old tasks before starting.
          imageQueue.Clean(imageView);
          ImageRef p=new ImageRef(url, imageView);

          synchronized(imageQueue.imageRefs) {
            imageQueue.imageRefs.push(p);
            imageQueue.imageRefs.notifyAll();
          }

          // Start thread if it's not started yet
          if(imageLoaderThread.getState() == Thread.State.NEW)
            imageLoaderThread.start();
        }




    private class ImageRef {
          public String url;
          public ImageView imageView;

          public ImageRef(String u, ImageView i) {
            url=u;
            imageView=i;
          }
        }

    private class ImageQueue {
          private Stack<ImageRef> imageRefs = new Stack<ImageRef>();

          //removes all instances of this ImageView
          public void Clean(ImageView view) {
            for(int i = 0 ;i < imageRefs.size();) {
              if(imageRefs.get(i).imageView == view)
                imageRefs.remove(i);
              else ++i;
            }
          }
    }

    private class ImageQueueManager implements Runnable {
          @Override
          public void run() {
            try {
              while(true) {
                // Thread waits until there are images in the 
                // queue to be retrieved
                if(imageQueue.imageRefs.size() == 0) {
                  synchronized(imageQueue.imageRefs) {
                    imageQueue.imageRefs.wait();
                  }
                }

                // When we have images to be loaded
                if(imageQueue.imageRefs.size() != 0) {
                  ImageRef imageToLoad;

                  synchronized(imageQueue.imageRefs) {
                    imageToLoad = imageQueue.imageRefs.pop();
                  }

                  Bitmap bmp = getBitmap(imageToLoad.url);
                  imageMap.put(imageToLoad.url, bmp);
                  Object tag = imageToLoad.imageView.getTag();

                  // Make sure we have the right view - thread safety defender
                  if(tag != null && ((String)tag).equals(imageToLoad.url)) {
                    BitmapDisplayer bmpDisplayer = 
                      new BitmapDisplayer(bmp, imageToLoad.imageView);

                    Activity a = 
                      (Activity)imageToLoad.imageView.getContext();

                    a.runOnUiThread(bmpDisplayer);
                  }
                }

                if(Thread.interrupted())
                  break;
              }


            }
             catch (InterruptedException e) {}
          }



private Bitmap getBitmap(String url) {
      String filename = String.valueOf(url.hashCode());
      File f = new File(cacheDir, filename);

      // Is the bitmap in our cache?
      Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
      if(bitmap != null) return bitmap;

      // Nope, have to download it
      try {
        bitmap = 
        BitmapFactory.decodeStream(new URL(url).openConnection().getInputStream());
        // save bitmap to cache for later
        writeFile(bitmap, f);

        return bitmap;
      } catch (Exception ex) {
        ex.printStackTrace();
        return null;
      }
    }

    private void writeFile(Bitmap bmp, File f) {
      FileOutputStream out = null;

      try {
        out = new FileOutputStream(f);
        bmp.compress(Bitmap.CompressFormat.PNG, 80, out);
      } catch (Exception e) {
        e.printStackTrace();
      }
      finally { 
        try { if (out != null ) out.close(); }
        catch(Exception ex) {} 
      }
    }
}

    public void displayImage(String url, Activity activity, ImageView imageView) {


        if(imageMap.containsKey(url)) {

            Bitmap bitmapToShow = imageMap.get(url);

            if(bitmapToShow != null) {
            //> Image was cached well
            imageView.setImageBitmap(bitmapToShow);
            return;
            }
            }

            //> Image was cached failed
        else {
            imageView.setImageResource(R.drawable.btn_radio);
            queueImage(url,imageView);
            return;
            }



        }

    private class BitmapDisplayer implements Runnable {
          Bitmap bitmap;
          ImageView imageView;

          public BitmapDisplayer(Bitmap b, ImageView i) {
            bitmap=b;
            imageView=i;
          }

          public void run() {
            if(bitmap != null)
              imageView.setImageBitmap(bitmap);
            else
              imageView.setImageResource(R.drawable.spinner_background);
          }
        }


}

每次需要显示视图时都会调用getView方法,由于这种下载图像的方法会为每个视图下载图像,因此每次都会用新图像加载视图,为了避免这种情况,您需要实现某种类型的缓存,要实现缓存,您可以使用可能具有位图的hashmap或arraylist,但由于列表大小增加,可能会导致OutOfMemory,所以您可以在文件系统中实现缓存,请按照示例实现缓存:

if( v == null){
        LayoutInflater li = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = li.inflate(R.layout.list_item,null);
        holder = new ViewHolder();

    holder.name = (TextView)v.findViewById(R.id.name);
    holder.text = (TextView)v.findViewById(R.id.text);
    holder.displayPic = (ImageView)v.findViewById(R.id.DisplayPicture);
    v.setTag(holder);

    }

    else
    {
        holder = (ViewHolder)v.getTag();

        obj = objs.get(position);
        if (obj != null)
        {
            holder.name.setText(obj.Name);
            holder.text.setText(""+obj.snippet);
            holder.displayPic.setTag(obj.ImageUrl);
            imageManager.displayImage(obj.ImageUrl, activity, holder.displayPic);

        }
}