0

I have been trying to figure out why bitmap is giving me a size value within the SimpleTarget but is null soon as am outside the SimpleTarget.

private Bitmap getImage(String path){

    final Bitmap[] bitmaps = new Bitmap[1];

    Glide.with(getApplicationContext())
            .load(path)
            .asBitmap()
            .into(new SimpleTarget<Bitmap>() {
                @Override
                public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                    bitmaps[0] = resource;
                    Log.v(TAG, "bitmap: " + bitmaps[0].getByteCount());// Returns a value as expected.
                }
            });
        Log.v(TAG, "bitmap2: " + bitmaps[0].getByteCount());// throws a null object reference.
        return bitmaps[0];
    }

Edit: AsyncTask approach.

private Bitmap getImage(String path){

    final Bitmap[] bitmaps = new Bitmap[1];

    new AsyncTask<Void, Void, Void>() {
        Bitmap tmp;

        @Override
        protected Void doInBackground(Void... params) {
            try {
                tmp = Glide.with(getApplicationContext())
                        .load("http://i.annihil.us/u/prod/marvel/i/mg/b/40/image_not_available.jpg")
                        .asBitmap()
                        .into(-1,-1)
                        .get();
            } catch (final ExecutionException | InterruptedException e) {
                Log.e(TAG, e.getMessage());
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void dummy) {
            if (null != tmp) {
                // The full bitmap should be available here
                bitmaps[0] = tmp;
                Log.v(TAG, "bitmap: " + bitmaps[0].getHeight());
                Log.d(TAG, "Image loaded");
            };
        }
    }.execute();

        Log.v(TAG, "bitmap2: " + bitmaps[0].getHeight());// throws a null object reference.
        return bitmaps[0];
    }

Edit: Added log in relation to the issue.

08-04 19:35:03.687 5183-5183/com.example.comics V/com.example.comics.MainActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getHeight()' on a null object reference
08-04 19:35:03.709 5183-5183/com.example.comics V/com.example.comics.backend.services.BackgroundService: bitmap: 537

Edit: If bitmap is not defined as final it will shout being accessed from inner class. Declare as final.

2 Answers2

1

You are creating a reference to a parameter and using it outside its function, bitmap[0] will be null when you leave the function.

You have to either create a copy of the bitmap using the following code:
bitmaps[0] = resource.copy(resource.getConfig(), true);

You should use this inside onResourceReady() body.

Or using Glide:

bitmaps[0] = Glide.with(getApplicationContext())
        .load(path)
        .asBitmap()
        .into ....
        .get();`

You need to wrap this inside a function in an asynctask and execute it. See this answer which explains loading in the background and setting the bitmap to an imageview inside the overrriden onPostExecute().

Vanna
  • 746
  • 1
  • 7
  • 16
  • Okay I didn't know that. I did try as you suggested. First example produces the same issue, and the 2nd example I get an error in the logcat informing me I need to run on a background thread. I am doing these operations in a Java thread within a Service class. – James Edward Smith Aug 04 '17 at 21:56
  • Sorry Vanna I have tried everything you said. I always come to the same result. During my research I did notice some did advise avoid using the bitmaps[0] = Glide.with(getApplicationContext()) approach as it can bring down the performance. The other 2 you referred isn't exactly what am expecting. – James Edward Smith Aug 04 '17 at 23:31
  • The Async task approach gave me the same issue. onPostExecute() could log.V size. Outside the Async I only got an null exception. – James Edward Smith Aug 04 '17 at 23:38
  • You can't return the resource that was one of the first things I did consider. Its because the SimpleTarget is more of an inner method rather than the method, which is wanting to return the bitmap. – James Edward Smith Aug 05 '17 at 00:27
0

I have finally got it to function. 1st the bitmap had to be declared in the global workspace. (Just as an object). 2nd the Log.v had to be in an if statement, since the database is being downloaded using a Restful client service. Its not always getting the intended data.

My solution:

Edit: Bitmap bitmap = null;

private Bitmap getImage(final String path){

    new AsyncTask<Void, Void, Void>() {

        @Override
        protected Void doInBackground(Void... params) {
            try {
                bitmap = Glide.with(getApplicationContext())
                        .load(path)
                        .asBitmap()
                        .into(-1,-1)
                        .get();
            } catch (final ExecutionException | InterruptedException e) {
                Log.e(TAG, e.getMessage());
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void dummy) {
        }
    }.execute();

    if(bitmap != null) {
        Log.v(TAG, "bitmap2: " + bitmap.getHeight());
    }
        return bitmap;
    }

However there is an error performing after the first 30 images. Am guessing its due to the method being called from a for loop, and resulting in the nasty list of errors.

08-04 20:20:21.191 12350-12457/com.example.comics E/com.example.comics.backend.services.BackgroundService: java.io.IOException: Request failed 404: Not Found
08-04 20:20:21.658 12350-12457/com.example.comics E/com.example.comics.backend.services.BackgroundService: java.io.IOException: Request failed 404: Not Found