Fresco内部非難による初のネットワークからのPNG画像のロードに失敗
6608 ワード
問題の説明のように、この問題はプロジェクトの中で長い間存在していたが、今日は自分の機能がトップページにあるため、初めて起動した体験が極めて悪いので、無理にこの問題を解決した.まず、どのような悪い体験を説明しましょう.つまり、私が初めてネットワークPNGをロードしたとき(その理由が分からなかった)、ずっとデフォルトの画像が表示されていましたが、もともとFrescoのメカニズムでは、まずデフォルトの画像を表示し、それからネットワークに行って画像をロードし、画像がダウンロードされると元のデフォルトの画像を置き換えます.
に感謝https://github.com/facebook/fresco/issues/1803この文章は私に考えを持たせた.
実はその前に私はすでに间违った位置に着いて、私は画像のコールバックの中でログを打って、ロードしていない画像がすべてonFailureの方法を歩いたことを発见して、1つの异常を投げ出しました
この異常はBitmapFactoryでJAvaの中から投げ出されたのは、4つの場所で投げ出されています.それぞれ異なるdecodeResource、decodeByteArray、decodeStream、decodeFileDescriptorのいくつかの方法で投げ出されています.その中の1つのdecodeStreamを見てみましょう.
bitmapを変換したときに投げ出されたのが見えます.その文章と結びつけて,FrescoがPNGをネットワークにロードしたときにBUGがビットマップとしてストリームを解析したときに異常を投げ出すと結論した.
では、問題を解決しましょう.ここで私の解決策を話します.
1つ目の案は、リンクの中でFrescoのソースコードを修正することです.1.3.0バージョンの432行をめくることができます.ここで見つけました.
次のifに&&encodedImageを加えます.getImageFormat() == DefaultImageFormats.PNG
今は1.8.0バージョンのFrescoなので、このクラスを探してこの場所に変更することができます.
第2のスキームは反射で第1のスキームの中のこの方法を修正して、これはFrescoのソースコードを修正しないことができます
3つ目の案は、私はこの案を使っています.私たちのAppの画像は7牛が存在しているので、あなたのUrlの後ろに追加すればいいです.
pngを七牛でjpgに変えることで完璧に解決しました.しかし、app全体がjpg形式の画像であることは不可能なので、上記の2つのスキームのうちの1つが必要かもしれません.もっといい案があれば、教えてください.開源万歳.
に感謝https://github.com/facebook/fresco/issues/1803この文章は私に考えを持たせた.
実はその前に私はすでに间违った位置に着いて、私は画像のコールバックの中でログを打って、ロードしていない画像がすべてonFailureの方法を歩いたことを発见して、1つの异常を投げ出しました
IllegalArgumentException Problem decoding into existing bitmap
この異常はBitmapFactoryでJAvaの中から投げ出されたのは、4つの場所で投げ出されています.それぞれ異なるdecodeResource、decodeByteArray、decodeStream、decodeFileDescriptorのいくつかの方法で投げ出されています.その中の1つのdecodeStreamを見てみましょう.
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
// we don't throw in this case, thus allowing the caller to only check
// the cache, and not force the image to be decoded.
if (is == null) {
return null;
}
Bitmap bm = null;
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
try {
if (is instanceof AssetManager.AssetInputStream) {
final long asset = ((AssetManager.AssetInputStream) is).getNativeAsset();
bm = nativeDecodeAsset(asset, outPadding, opts);
} else {
bm = decodeStreamInternal(is, outPadding, opts);
}
if (bm == null && opts != null && opts.inBitmap != null) {
throw new IllegalArgumentException("Problem decoding into existing bitmap");
}
setDensityFromOptions(bm, opts);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
}
return bm;
}
bitmapを変換したときに投げ出されたのが見えます.その文章と結びつけて,FrescoがPNGをネットワークにロードしたときにBUGがビットマップとしてストリームを解析したときに異常を投げ出すと結論した.
では、問題を解決しましょう.ここで私の解決策を話します.
1つ目の案は、リンクの中でFrescoのソースコードを修正することです.1.3.0バージョンの432行をめくることができます.ここで見つけました.
public class DecodeProducer implements Producer<CloseableReference<CloseableImage>> {
//......
@Override
protected synchronized boolean updateDecodeJob(EncodedImage encodedImage, boolean isLast) {
boolean ret = super.updateDecodeJob(encodedImage, isLast);
if (!isLast && EncodedImage.isValid(encodedImage) &&
encodedImage.getImageFormat() == DefaultImageFormats.JPEG) {
if (!mProgressiveJpegParser.parseMoreData(encodedImage)) {
return false;
}
int scanNum = mProgressiveJpegParser.getBestScanNumber();
if (scanNum <= mLastScheduledScanNumber) {
// We have already decoded this scan, no need to do so again
return false;
}
if (scanNum < mProgressiveJpegConfig.getNextScanNumberToDecode(mLastScheduledScanNumber)
&& !mProgressiveJpegParser.isEndMarkerRead()) {
// We have not reached the minimum scan set by the configuration and there
// are still more scans to be read (the end marker is not reached)
return false;
}
mLastScheduledScanNumber = scanNum;
}
return ret;
}
//......
}
次のifに&&encodedImageを加えます.getImageFormat() == DefaultImageFormats.PNG
if (scanNum < mProgressiveJpegConfig.getNextScanNumberToDecode(mLastScheduledScanNumber)
&& !mProgressiveJpegParser.isEndMarkerRead()) {
// We have not reached the minimum scan set by the configuration and there
// are still more scans to be read (the end marker is not reached)
return false;
}
今は1.8.0バージョンのFrescoなので、このクラスを探してこの場所に変更することができます.
第2のスキームは反射で第1のスキームの中のこの方法を修正して、これはFrescoのソースコードを修正しないことができます
3つ目の案は、私はこの案を使っています.私たちのAppの画像は7牛が存在しているので、あなたのUrlの後ろに追加すればいいです.
"?imageView2/1/format/jpg"
pngを七牛でjpgに変えることで完璧に解決しました.しかし、app全体がjpg形式の画像であることは不可能なので、上記の2つのスキームのうちの1つが必要かもしれません.もっといい案があれば、教えてください.開源万歳.