java - 关于android调试器的奇怪现象(CloseableReference)

标签 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 循环,它不会返回任何内容! 继续看和不看有什么区别吗???

watch 显示imgList中的元素,当index=1和4时,我点击了步入。

enter image description here

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

enter image description here 或者因为我没有以标准化方式使用此类CloseableReference

最佳答案

让我尝试解释一下这里发生的情况。

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

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

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

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

关于java - 关于android调试器的奇怪现象(CloseableReference),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37293104/

相关文章:

java - 你能在JSP(Firefox和IE)中获取Windows(AD)用户ID吗?

android - 在我的 Activity 中保留切换按钮状态

android - Admob 广告在模拟器中显示,但在 Admob 帐户中没有状态

java - 根据当前背景更改按钮背景

android - 在 android 上使用 Fresco 库显示来自 SD 卡的图像

android - SimpleDraweeView 在使用 Fresco 替换图像时出现黑色闪烁

java - 事务注释不起作用

java - JSP访问中的HashMap<HashMap<Integer, Integer>, String>

java - 如何防止 try-with-resources 从 lines() (Stream<String>) 关闭 BufferedReader?

android - 我在 Fresco 中遇到圆形图像问题