关于android Debugger(CloseableReference)的奇怪现象

时间:2016-05-18 07:38:13

标签: java android fresco

我有一个循环:

    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
}

,方法createBitmapRefer(int count)如下:

    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);
        }

    }

当我调试时,如果我单击步进并逐步查看代码,它将按照我的意愿返回一个CloseableReference,并且imgList(它的一个ArrayList)也可以获取该元素。但如果我跳过for循环,它什么都不返回! 看看它与否之间有什么不同吗?

手表显示imgList中的元素,当index = 1和4时,我点击进入。

enter image description here

并且logcat显示Log.i()打印的内容。

enter image description here 或者因为我没有以标准化的方式使用这个课程CloseableReference

1 个答案:

答案 0 :(得分:0)

让我试着解释一下这里发生了什么。

  1. 您没有按预期方式使用Fresco。如果您只是需要显示图像,我会退一步并强烈建议您使用SimpleDraweView。但是,如果你真的需要底层位图,你可以从ImagePipeline中获得类似于你已经做过的方式,但只有一个关键区别。提取图像是异步发生的。这意味着你不能只做dataSource = pipeline.fetchDecodedImage(...)然后立即dataSource.getResult。如果在内存缓存中找不到图像,getResult将只返回null。您需要做的是subscribeDataSource,如Fresco documentation中所述。如果您打算直接使用它,我强烈建议您阅读少数chapters about ImagePipeline。否则,您可能会因为渲染回收的位图而导致应用程序泄漏内存或崩溃。

  2. 您在调试器中看到的正是我上面所描述的。大小为5的数组如下所示:

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

  3. AndroidStudio UI只是为了简洁而隐藏了空条目。如果您不喜欢通过右键单击并打开选项,可以将其关闭。你获得1和4的原因是因为图像已经在位图内存缓存中找到并立即从中检索。您为0,2和3获取null的原因是因为尚未加载图像。 Fresco可能需要下载图像,即使已经下载并在磁盘缓存中,也可能需要对图像进行解码。所有这些都需要一些时间,而不是瞬间完成。这就是您需要订阅回调的原因,ImagePipeline会在图像准备就绪时通知您。