关于 android 调试器的奇怪现象 (CloseableReference)
weird phenomenon about android Debugger (CloseableReference)
我有一个循环:
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);
}
}
我调试的时候,如果我点step into一步步看代码,它会return一个CloseableReference,就像我想要的那样,imgList(它是一个ArrayList)可以得到元素too.BUT 如果我越过 for 循环,它 return 什么都没有!
继续看和不看有区别吗???
watches显示imgList中的元素,当index=1和4时,我点了step into。
和 logcat 显示 Log.i()
打印的内容。
还是因为我没有以标准化方式使用此 classCloseableReference
?
让我试着解释一下这里发生了什么。
您没有按预期方式使用 Fresco。我将退一步并强烈建议您如果只需要显示图像,请使用 SimpleDraweView。但是,如果您确实需要底层位图,则可以通过类似于您已经在做的方式从 ImagePipeline 获取它,但有一个关键区别。获取图像是异步发生的。这意味着您不能只执行 dataSource = pipeline.fetchDecodedImage(...)
然后立即执行 dataSource.getResult
。如果在内存缓存中找不到图像,getResult
将只是 return null
。如果您打算直接使用它,您需要做的是 subscribe
到 DataSource
,如 Fresco documentation. I strongly suggest that you read those few chapters about ImagePipeline 中所述。否则,您可能会因为渲染回收位图而导致您的应用程序泄漏内存或崩溃。
你在调试器中看到的正是我上面描述的。大小为 5 的数组如下所示:
0 = 空,
1 = CloseableReference@4908,
2 = 空,
3 = 空,
4 = CloseableReference@5231
AndroidStudio UI 为简洁起见只是隐藏了空条目。如果您不喜欢它,可以通过右键单击并打开选项来关闭它。你得到 1 和 4 的东西的原因是因为图像已在位图内存缓存中找到并立即从中检索。 0、2 和 3 为 null 的原因是图像尚未加载。 Fresco 可能需要下载图像,即使它已经下载并在磁盘缓存中,它也可能需要解码图像。所有这些都需要一些时间,而且不是瞬间完成的。这就是为什么您需要订阅回调,ImagePipeline 会在图像准备就绪时通知您。
我有一个循环:
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);
}
}
我调试的时候,如果我点step into一步步看代码,它会return一个CloseableReference,就像我想要的那样,imgList(它是一个ArrayList)可以得到元素too.BUT 如果我越过 for 循环,它 return 什么都没有! 继续看和不看有区别吗???
watches显示imgList中的元素,当index=1和4时,我点了step into。
和 logcat 显示 Log.i()
打印的内容。
CloseableReference
?
让我试着解释一下这里发生了什么。
您没有按预期方式使用 Fresco。我将退一步并强烈建议您如果只需要显示图像,请使用 SimpleDraweView。但是,如果您确实需要底层位图,则可以通过类似于您已经在做的方式从 ImagePipeline 获取它,但有一个关键区别。获取图像是异步发生的。这意味着您不能只执行
dataSource = pipeline.fetchDecodedImage(...)
然后立即执行dataSource.getResult
。如果在内存缓存中找不到图像,getResult
将只是 returnnull
。如果您打算直接使用它,您需要做的是subscribe
到DataSource
,如 Fresco documentation. I strongly suggest that you read those few chapters about ImagePipeline 中所述。否则,您可能会因为渲染回收位图而导致您的应用程序泄漏内存或崩溃。你在调试器中看到的正是我上面描述的。大小为 5 的数组如下所示:
0 = 空, 1 = CloseableReference@4908, 2 = 空, 3 = 空, 4 = CloseableReference@5231
AndroidStudio UI 为简洁起见只是隐藏了空条目。如果您不喜欢它,可以通过右键单击并打开选项来关闭它。你得到 1 和 4 的东西的原因是因为图像已在位图内存缓存中找到并立即从中检索。 0、2 和 3 为 null 的原因是图像尚未加载。 Fresco 可能需要下载图像,即使它已经下载并在磁盘缓存中,它也可能需要解码图像。所有这些都需要一些时间,而且不是瞬间完成的。这就是为什么您需要订阅回调,ImagePipeline 会在图像准备就绪时通知您。