Android Java编码:如何访问列表视图的下载图像

时间:2013-12-07 19:25:46

标签: java android image listview

通过修改教程代码来尝试不同的工作来学习。我现在还处于严肃的学习阶段,请原谅这个问题,如果它听起来无知。我有以下代码,我正在通过解析的XML文件(从教程/示例)下载图像文件:

public class ImageDownloader {

Map<String,Bitmap> imageCache;

public ImageDownloader(){
    imageCache = new HashMap<String, Bitmap>();

}

//download function
public void download(String url, ImageView imageView) {
     if (cancelPotentialDownload(url, imageView)) {

         //Caching code right here
         String filename = url.substring(url.lastIndexOf('/') + 1);
         File f = new File(getCacheDirectory(imageView.getContext()), filename);

          // Is the bitmap in our memory cache?
         Bitmap bitmap = null;

          bitmap = (Bitmap)imageCache.get(f.getPath());

          if(bitmap == null){

              bitmap = BitmapFactory.decodeFile(f.getPath());

              if(bitmap != null){
                  imageCache.put(f.getPath(), bitmap);
              }

          }
          //No? download it
          if(bitmap == null){
              BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
              DownloadedDrawable downloadedDrawable = new   DownloadedDrawable(task);
              imageView.setImageDrawable(downloadedDrawable);
              task.execute(url);
          }else{
              //Yes? set the image
              imageView.setImageBitmap(bitmap);
          }
     }
}

//cancel a download (internal only)
private static boolean cancelPotentialDownload(String url, ImageView imageView) {
    BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);

    if (bitmapDownloaderTask != null) {
        String bitmapUrl = bitmapDownloaderTask.url;
        if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
            bitmapDownloaderTask.cancel(true);
        } else {
            // The same URL is already being downloaded.
            return false;
        }
    }
    return true;
}

//gets an existing download if one exists for the imageview
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
    if (imageView != null) {
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof DownloadedDrawable) {
            DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
            return downloadedDrawable.getBitmapDownloaderTask();
        }
    }
    return null;
}

//our caching functions
// Find the dir to save cached images
private static File getCacheDirectory(Context context){
    String sdState = android.os.Environment.getExternalStorageState();
    File cacheDir;

    if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
        File sdDir = android.os.Environment.getExternalStorageDirectory();  

        //TODO : Change your diretcory here
        cacheDir = new File(sdDir,"data/fresh/images");
    }
    else
        cacheDir = context.getCacheDir();

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

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) {} 
      }
}
///////////////////////

//download asynctask
public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
    private String url;
    private final WeakReference<ImageView> imageViewReference;

    public BitmapDownloaderTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    // Actual download method, run in the task thread
    protected Bitmap doInBackground(String... params) {
         // params comes from the execute() call: params[0] is the url.
         url = (String)params[0];
         return downloadBitmap(params[0]);
    }

    @Override
    // Once the image is downloaded, associates it to the imageView
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
            // Change bitmap only if this process is still associated with it
            if (this == bitmapDownloaderTask) {
                imageView.setImageBitmap(bitmap);

                //cache the image

                String filename = url.substring(url.lastIndexOf('/') + 1);
                //String filename = String.valueOf(url.hashCode());
                File f = new File(getCacheDirectory(imageView.getContext()), filename);

                imageCache.put(f.getPath(), bitmap);

                writeFile(bitmap, f);
            }
        }
    }


}

static class DownloadedDrawable extends ColorDrawable {
    private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;

    public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
        super(Color.BLACK);
        bitmapDownloaderTaskReference =
            new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
    }

    public BitmapDownloaderTask getBitmapDownloaderTask() {
        return bitmapDownloaderTaskReference.get();
    }
}

//the actual download code
static Bitmap downloadBitmap(String url) {
    HttpParams params = new BasicHttpParams();
    params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    HttpClient client = new DefaultHttpClient(params);
    final HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) { 
            Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url); 
            return null;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent(); 
                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            } finally {
                if (inputStream != null) {
                    inputStream.close();  
                }
                entity.consumeContent();
            }
        }
    } catch (Exception e) {
        // Could provide a more explicit error message for IOException or IllegalStateException
        getRequest.abort();
        Log.w("ImageDownloader", "Error while retrieving bitmap from " + url + e.toString());
    } finally {
        if (client != null) {
            //client.close();
        }
    }
    return null;
}
}

然后我有一个列表视图,其中包含以下代码以获取图像:

  String uri = "drawable/"+ downloadedImgs.get(position).get(KEY_ICON);
          int imageResource =   holwtt.getContext().getApplicationContext().getResources().getIdentifier(uri, null, holwtt.getContext().getApplicationContext().getPackageName());
          Drawable image = holwtt.getContext().getResources().getDrawable(imageResource);
          holder.firstImg.setImageDrawable(image);

我想我明白使用getResources()并不是我访问图片所需要的。问题是我尝试过的一切都不起作用,getPath()等。 图像将在应用程序中使用,但会更改,因此在apk中包含它们不是一个选项。还试图考虑是否安装了SD卡,因此存在不使用硬编码目录路径的问题。 我感谢您的建议和意见。

1 个答案:

答案 0 :(得分:0)

在这段代码中有很多东西是不对的。 当你正在学习时,我会给你一些示例代码,这样你就可以开始并让你继续学习更好的方向。请注意,根据Android文档的建议,可以使用HttpUrlConnection而不是HttpClient来改进您的代码。另请注意,图像的url会转换为整数哈希,因此您可以将其用作文件的名称。也可以使用内部或外部存储。这只是AsyncTask,我希望你多挖一点,然后自己创建图像适配器。继续!

public static class ImageCacher extends AsyncTask<String, String, Integer>{

    Context context;
    ImageView iv;
    Bitmap b;


    public ImageCacher(Context context, ImageView iv){
        this.context = context;
        this.iv = iv;
    }

    @Override
    protected Integer doInBackground(String... params) {

        for(String p:params){
            //Modification to get relative urls
            final String param;
            if(!p.startsWith("http")){
                param = URL_BASE+p;
            }else{
                param = p;
            }

            //check if already CACHED
            File file = getFileForCachedImage(param);

            b = getCachedImage(file);
            if(b != null){
                if(iv != null){
                    iv.post(new Runnable() {

                        public void run() {
                            String tag = (String) iv.getTag();
                            if(tag != null){
                                if(tag.matches(param))
                                    iv.setImageBitmap(b);
                            }

                        }
                    });
                }

                return 0;
            }else{
                file.delete();
            }

            //download
            //file = new File(context.getFilesDir(), filename); //OLD way
            file = getFileForCachedImage(param);
            b = saveImageFromUrl(context, param);
            if(b != null){
                if(iv != null){
                    iv.post(new Runnable() {

                        public void run() {
                            String tag = (String) iv.getTag();
                            if(tag != null){
                                if(tag.matches(param))
                                    iv.setImageBitmap(b);
                            }

                        }
                    });
                }
            }
        }

        return 0;
    }

}

/**
 * Gets an image given its url
 * @param param
 */
public static Bitmap saveImageFromUrl(Context context, String fullUrl) {
    Bitmap b = null;

    try {
        URL url = new URL(fullUrl);
        URLConnection conn = url.openConnection();
        conn.setDoInput(true);
        conn.connect();
        //save bitmap to file
        InputStream is = conn.getInputStream();
        //String filename = String.format("%d", fullUrl.hashCode()); //ORIGINAL way
        //File file = new File(context.getFilesDir(), filename);    //original way
        File file = getFileForCachedImage(fullUrl);
        if(file.exists()){
            //delete
            file.delete();
            file=null;
        }
        //file = new File(context.getFilesDir(), filename);  //ORIGINAL way
        file = getFileForCachedImage(fullUrl);

        FileOutputStream out = new FileOutputStream(file);
        byte buffer[] = new byte[256];
        while(true){
            int cnt = is.read(buffer);
            if(cnt <=0){
                break;
            }
            out.write(buffer,0, cnt);
        }

        out.flush();
        out.close();
        is.close();

        b = BitmapFactory.decodeFile(file.getAbsolutePath());

    } catch (Exception e) {
    //  e.printStackTrace();
    }

    return b;
}

/**
 * Gets the file to cache the image
 * @param url
 * @return
 */
public static File getFileForCachedImage(String url) {

    /**
     * Modification for relative urls
     */
    if(!url.startsWith("http")){
        url = URL_BASE+url;
    }

    String filename = String.format("%d.cached", url.hashCode());

    /**
     * External storage
     */
    File file = new File(Environment.getExternalStorageDirectory(), EXT_DIR_NAME+"/"+filename);  //EXTERNAL storage
    String parent = file.getParent();
    if(parent != null){
        new File(parent).mkdirs();
    }

    /**
     * Internal storage
     */
    //File file = new File(context.getFilesDir(), filename);  //INTERNAL storage

    return file;

}

/**
 * Returns a bitmap object if cached
 * @param file
 * @return
 */
public static Bitmap getCachedImage(File file) {

    try {
        return BitmapFactory.decodeFile(file.getAbsolutePath());
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}