Search code examples
javaandroidfresco

weird phenomenon about android Debugger (CloseableReference)


There I have a loop:

    public void updateDrawee(View view) {
            if (begin) {
                begin = false;
                for (int i = 0; i < 5; i++) {
                    CloseableReference<CloseableImage> reference = createBitmapRefer(i);
                    Log.i("reference", reference+"");
                    imgList.add(reference);
                }Log.i("imgList", imgList.toString());Log.i("imgList.0", imgList.get(0)+"");
            }
    //...some code
}

and the method createBitmapRefer(int count) follow:

    public CloseableReference<CloseableImage> createBitmapRefer(int count) {
        ImagePipeline pipeline = Fresco.getImagePipeline();
        int[] drawableIds = {R.drawable.alpha1, R.drawable.alpha2,
                R.drawable.alpha3, R.drawable.alpha4, R.drawable.alpha5};

        ImageRequest levelRequest
                = ImageRequestBuilder.newBuilderWithResourceId(drawableIds[count])//++
                .setProgressiveRenderingEnabled(true)//逐行加载
                .build();

        CloseableReference<CloseableImage> bmpReference = null;

        DataSource<CloseableReference<CloseableImage>> dataSource
                = pipeline.fetchImageFromBitmapCache(levelRequest, this);
        try {
            if (!dataSource.hasResult()) {
                dataSource = pipeline.fetchDecodedImage(levelRequest, this);
            }
            //count %= 5;

            Log.i("dataSource has result", dataSource.hasResult() +"");
            Log.i("dataSource fail?", dataSource.hasFailed() + "");
            bmpReference = dataSource.getResult();
            Log.i("bmpRefer", bmpReference+"");
            if (bmpReference != null) {
                CloseableReference<CloseableImage> returnRef;
                returnRef = bmpReference.clone();
                return returnRef;
            }else {
                return null;
            }
        }finally {
            dataSource.close();
            CloseableReference.closeSafely(bmpReference);
        }

    }

when I debug, if i click step into and see the code step by step, it will return a CloseableReference just as I want, and the imgList(its a ArrayList) can get the element too.BUT if I step over the for loop, it return nothing! Is there any different between keep looking at it or not???

the watches show elements in imgList, when index=1 and 4, I clicked step into.

enter image description here

and the logcat show what Log.i() print.

enter image description here Or because I have not use this classCloseableReference in Standardized way?


Solution

  • Let me try to explain what happens here.

    1. You are not using Fresco in the intended way. I will step back for a moment and strongly suggest that you use SimpleDraweView if you just need to display images. If however you really need the underlying bitmap, you can get it from the ImagePipeline in way similar to what you already doing, but with one key difference. Fetching images happens asynchronously. What that means is that you can't just do dataSource = pipeline.fetchDecodedImage(...) and then immediately dataSource.getResult. If the image was not found in the memory cache, getResult will just return null. What you need to do instead is to subscribe to the DataSource as explained in the Fresco documentation. I strongly suggest that you read those few chapters about ImagePipeline if you intend to use it directly. Otherwise you may cause your app to leak the memory or to crash because of rendering recycled bitmap.

    2. What you see in debugger is exactly what I described above. The array of size 5 looks like this:

      0 = null, 1 = CloseableReference@4908, 2 = null, 3 = null, 4 = CloseableReference@5231

    The AndroidStudio UI just hides the null entries for brevity. You can turn this off if you don't like it by right-clicking there and opening options. The reason you get something for 1 and 4 is because the image has been found in the bitmap memory cache and was retrieved from it immediately. The reason you get null for 0, 2 and 3 is because the image has not been loaded yet. Fresco might need to download the image, and even if it is already downloaded and in the disk cache, it may need to decode the image. All of this takes some time and is not instantaneous. That's why you need to subscribe your callback and ImagePipeline will notify you when the image is ready.