Pergunta

I am trying to get the file size of an image I've downloaded and saved using this AsyncTask

protected Bitmap doInBackground(String... params) {
      String urldisplay = params[0];

      if(params[1] != null)
          newClan = params[1];

      if(params[2] != null){
          Context ctx = Home.getContext();

          prevClan = params[2];
          File f  = new File(ctx.getFilesDir(), prevClan + ".png");
          if(f.exists()){
              File d = f.getAbsoluteFile();
              d.delete();
          }
      }

      Bitmap emblem = null;

        try {
            //get emblem from url
            InputStream  in = new java.net.URL(urldisplay).openStream();
            emblem = BitmapFactory.decodeStream(in);
        } catch (MalformedURLException e) {
            Log.e(e.getClass().toString(), e.getMessage());
        } catch (IOException e) {
            Log.e(e.getClass().toString(), e.getMessage());
        }

      return emblem;
  }

  public static void saveImage(Bitmap img){

      Context ctx = Home.getContext();

      try {
        FileOutputStream out = new FileOutputStream(ctx.getFilesDir().getPath() + File.separatorChar + newClan + ".png");
        img.compress(Bitmap.CompressFormat.PNG, 100, out);
    } catch (FileNotFoundException e) {
    } catch (NullPointerException e1) {
        Log.e("NullPointerException DownloadImageTask", e1.toString());//TODO
    }
  }

This is called like so

File emblemPath = new File(ctx.getFilesDir(), clan + ".png");
    Log.e("image size", emblemPath.length()+"");//TODO

    if(emblemPath.exists()){
        emb.setImageDrawable(Drawable.createFromPath(emblemPath.toString()));
        Log.e("Image exists", "size = " + emblemPath.length());//TODO
    }
    else{
        String prevClan = pref.getString("prevClan", null);
        emb.setImageBitmap(Storage.updateClanEmb(embURL, clan, prevClan));
        Log.e("Image downloaded", "size = " + emblemPath.length());//TODO
    }

I have a login screen directly before this that supplies the needed variables. The downloaded image shows correctly in the ImageView but the file size is 0 the first time, after logging out and then back in, it shows the correct file size. The log is here:

- 05-25 04:52:32.973: E/result(22501): {"login":0,"clan":"Cosa Nostra","status":"0"}
- 05-25 04:52:32.984: E/Login success!(22501): Login success!
- 05-25 04:52:34.554: E/image size(22501): 0
- 05-25 04:52:35.953: E/Image downloaded(22501): size = 0
- 05-25 04:52:44.553: E/Logout(22501): Logged out
- 05-25 04:52:54.893: E/result(22501): {"login":0,"clan":"Cosa Nostra","status":"0"}
- 05-25 04:52:54.893: E/Login success!(22501): Login success!
- 05-25 04:52:57.034: E/image size(22501): 2461
- 05-25 04:52:57.094: E/Image exists(22501): size = 2461

Why is the file size not correct after saving the image? Am I accessing it wrong? As a side note, I'm a newbie at Android and haven't fully grasped how to use contexts. I fear this might be my issue. In the code, Home is the activity that this is being called from.

EDIT: I added this line to the onPostExecute() at @Samarth's request

iv.setImageBitmap(result);

where iv is the ImageView that displays the downloaded image. The resulting log was exactly the same. Could someone explain the advantage of setting the image in the AsyncTask's onPostExecute() method? I seem to have forgotten to include my updateClanEmblem method so here it is:

/**
 * Method to call DownloadImageTask which downloads then saves the updated clan emblem
 * 
 * @param iv The ImageView to set the emblem to
 * @param url The URL, as a String, to the page containing ONLY the clan emblem.
 * @param newClan The new clan emblem to download.
 * @param prevClan The old clan emblem to delete. Can be null.
 */
public static void updateClanEmb(ImageView iv, String url, String newClan, String prevClan){
    String[] params = {
            url,
            newClan,
            prevClan,
    };

    try {
        new DownloadImageTask(iv).execute(params).get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}
Foi útil?

Solução 2

After a bit of struggle, I've found my solution. The AsyncTask hadn't finished before I tried to check the file size. I was under the impression that the .get() method would make it wait until it was done, but I was wrong. The reason I did not catch this sooner was that I made a mistake and was checking the wrong file in the AsyncTask so was getting misleading information.

What I've learned from this: the .get() method of the AsyncTask does not always wait for the task to finish. Do whatever needs to be done in the onPostExecute() method or else it will not work as expected. I am still unsure what the .get() method does.

Outras dicas

You should be doing the image saving and assigning in the onPostExecute method of the AsyncTask. I think you are trying to set the image before it is being downloaded.

When are you calling that piece of code. Also when are you calling saveImage?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top