我的應用程序的特點是通過URLImage
和URLImage.ImageAdapter
填充了圖像的InfiniteScrollAdapter
。模擬器中的InfiniteScrollAdapter中的URLImage顯示NPE(CodenameOne)
在模擬器(Iphone3GS或Xoom或GoogleNexus7)中,NPE在第一次出現InfiniteScrollAdapter
時顯示,但該文件確實存在於服務器上。
請注意:在此測試中,數據庫中只有一個條目。所以在下面的圖片中,你應該看到的是同一行(圖片+文本)重複3次。
請注意,在未被顯示的圖標的順序可以不同
我用來下載圖像的代碼是:
Image tempPlaceholder = Image.createImage(
ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX,
ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX,
ParametresGeneraux.accentColor);
Graphics gr = tempPlaceholder.getGraphics();
gr.setAntiAliased(true);
gr.setColor(ParametresGeneraux.accentColor);
gr.fillArc(0, 0, ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX, ParametresGeneraux.SIZE_OF_REPORT_PIC_IN_PX, 0, 360);
EncodedImage roundPlaceholder = EncodedImage.createFromImage(tempPlaceholder, true);
final Image reportImage = URLImage.createToStorage(
roundPlaceholder,
photoFilenameInStorage,
currentReport.getPhotoPath(),
ParametresGeneraux.RESIZE_SCALE_WITH_ROUND_MASK
);
這裏是被覆蓋的imageAdapter方法:
public final static URLImage.ImageAdapter RESIZE_SCALE_WITH_ROUND_MASK = new URLImage.ImageAdapter() {
@Override
public EncodedImage adaptImage(EncodedImage downloadedImage, EncodedImage placeholderImage) {
final Image[] tmp = new Image[1];
if (!Display.getInstance().isEdt()) {
// The image scaling has to be called from EDT
Display.getInstance().callSeriallyAndWait(() -> {
tmp[0] = downloadedImage.scaledLargerRatio(placeholderImage.getWidth(), placeholderImage.getHeight());
if (tmp[0].getWidth() > placeholderImage.getWidth()) {
int diff = tmp[0].getWidth() - placeholderImage.getWidth();
int x = diff/2;
tmp[0] = tmp[0].subImage(x, 0, placeholderImage.getWidth(), placeholderImage.getHeight(), true);
} else if (tmp[0].getHeight() > placeholderImage.getHeight()) {
int diff = tmp[0].getHeight() - placeholderImage.getHeight();
int y = diff/2;
tmp[0] = tmp[0].subImage(0, y, Math.min(placeholderImage.getWidth(), tmp[0].getWidth()),
Math.min(placeholderImage.getHeight(), tmp[0].getHeight()), true);
}
});
} else {
tmp[0] = downloadedImage.scaledLargerRatio(placeholderImage.getWidth(), placeholderImage.getHeight());
if (tmp[0].getWidth() > placeholderImage.getWidth()) {
int diff = tmp[0].getWidth() - placeholderImage.getWidth();
int x = diff/2;
tmp[0] = tmp[0].subImage(x, 0, placeholderImage.getWidth(), placeholderImage.getHeight(), true);
} else if (tmp[0].getHeight() > placeholderImage.getHeight()) {
int diff = tmp[0].getHeight() - placeholderImage.getHeight();
int y = diff/2;
tmp[0] = tmp[0].subImage(0, y, Math.min(placeholderImage.getWidth(), tmp[0].getWidth()),
Math.min(placeholderImage.getHeight(), tmp[0].getHeight()), true);
}
}
EncodedImage[] image2Return = new EncodedImage[1];
if (!Display.getInstance().isEdt()) {
// The image scaling has to be called from EDT
Display.getInstance().callSeriallyAndWait(() -> {
Image roundMask = Image.createImage(tmp[0].getWidth(), tmp[0].getHeight(), 0xff000000);
Graphics gr = roundMask.getGraphics();
gr.setColor(0xffffff);
gr.fillArc(0, 0, tmp[0].getWidth(), tmp[0].getHeight(), 0, 360);
Object mask = roundMask.createMask();
tmp[0] = tmp[0].applyMask(mask);
image2Return[0] = EncodedImage.createFromImage(tmp[0], false);
});
} else {
Image roundMask = Image.createImage(tmp[0].getWidth(), tmp[0].getHeight(), 0xff000000);
Graphics gr = roundMask.getGraphics();
gr.setColor(0xffffff);
gr.fillArc(0, 0, tmp[0].getWidth(), tmp[0].getHeight(), 0, 360);
Object mask = roundMask.createMask();
tmp[0] = tmp[0].applyMask(mask);
image2Return[0] = EncodedImage.createFromImage(tmp[0], false);
}
return image2Return[0];
}
在堆棧跟蹤中,NPE似乎從重寫URLImage.ImageAdapter
幹:
java.lang.IllegalArgumentException異常:創建圖像失敗長度的給定 圖像數據:在 com.codename1 0 .ui.Image.createImage(Image.java:654)at com.codename1.ui.EncodedImage.getInternal(EncodedImage.java:365)at com.codename1.ui.EncodedImage.getInternalImpl(EncodedImage.java:340) at com.codename1.ui.EncodedImage.getHeight(EncodedImage.java:522)at com.codename1.ui.Image.scaledLa rgerRatio(Image.java:899)at com.my.application.ParametresGeneraux $ 1.lambda $ adaptImage $ 0(ParametresGeneraux.java:564) at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:95)at com.codename1.ui.Display.processSerialCalls(Display.java:1154)at com.codename1.ui.Display.edtLoopImpl(Display.java:1098)at com.codename1.ui.Display.invokeAndBlock(Display.java: 1207)at com.codename1.ui.Display.invokeAndBlock(Display.java:1244)at com.codename1.ui.URLImage $ DownloadCompleted.actionPerformed(URLImage.java:233) at com.codename1.ui.URLImage $ 4 .onSucess(URLImage.java:301)at com.codename1.ui.URLImage $ 4.onSucess(URLImage.java:297)at com.codename1.util.CallbackDispatcher.run(Cal lbackDispatcher.java:53) at com.codename1.ui.Display.processSerialCalls(Display.java:1154)at com.codename1.ui.Display.edtLoopImpl(Display.java:1098)at com.codename1.ui。 Display.mainEDTLoop(Display.java:999)at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176) [EDT] 0:0:0,1 - 代號一個修訂: e5c43877074c18b4b5c7748d000e5cfac75ab749 2318
[EDT] 0:0:0,1 - 例外:顯示java.lang.NullPointerException - 在 com.codename1空 顯示java.lang.NullPointerException .impl.javase.JavaSEPort.scale(JavaSEPort.java: 3996)at com.codename1.ui.Image.scale(Image。java:1007)at com.codename1.ui.Image.scaledImpl(Image.java:953)at com.codename1.ui.Image.scaled(Image.java:918)at com.codename1.impl.javase。 JavaSEPort $ 71.save(JavaSEPort.java:7659)at com.codename1.ui.EncodedImage.scaledEncoded(EncodedImage.java:626)at com.codename1.ui.EncodedImage.scaled(EncodedImage.java:653)at com .codename1.ui.Image.scaledLargerRatio(Image.java:904)at com.my.application.ParametresGeneraux $ 1.lambda $ adaptImage $ 0(ParametresGeneraux.java:564) at com.codename1.ui.RunnableWrapper.run(RunnableWrapper .java:95)at com.codename1.ui.Display.processSerialCalls(Display.java:1154)at com.codename1.ui.Display.edtLoopImpl(Display.java:1098)at com.codename1.ui.Display.invokeAndBlock(Display.java:1207)at com.codename1.ui.Display.invokeAndBlock(Display.java:1244)at com.codename1.ui.URLImage $ DownloadCompleted.actionPerformed(URLImage (URLImage.java:297)at com.codename1.util .CallbackDispatcher.run(CallbackDispatcher.java:53) at com.codename1.ui.Display.processSerialCalls(Display.java:1154)at com.codename1.ui.Display.edtLoopImpl(Display.java:1098)at com .codename1.ui.Display.mainEDTLoop(Display.java:999)at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)at com.codename1.impl.Co denameOneThread.run(CodenameOneThread.java:176)
而且,在.cn1目錄一目瞭然顯示了當一切作品,未經NPE不出現後綴「ImageURLTMP」的URLImage存儲文件名。最後,如果我以後再回到這個表單,所有事情都按預期工作(顯示圖像,不顯示NPE)。我試圖在imageAdapter
中測試downloadImage nullness,但EncodedImage不爲null。
我該如何避免這種NPE?
編輯2017年3月1日
在從@Diamond和@Shai的答案,我相信NPE發生的原因InfiniteScrollAdapter要填寫與行的屏幕,因此同時推出相同的圖像的下載(因爲它不在緩存中)。所以一個解決方案可以防止InfiniteScrollAdapter循環(所以它變得有限)。我怎樣才能做到這一點 ?
請注意,沒有404錯誤,網絡監視器顯示響應代碼200,如下所示。然而,圖像不應該被下載3次,應該嗎?
後您用來爲您的InfinteScroller的代碼片段和URLImage – Diamond
我忘了!看我的編輯@Diamond! – HelloWorld