BitmapFactory.decodeStreamメソッドnullのエラー解析を返す


この問題は実はとっくに出会って、数日止まって電気が働かないため、今日この問題を記録して分かち合います.BitmapFactoryを使用してネットワーク内のピクチャをロードする場合、decodeStreamメソッドを使用するとnullのエラーが返されます.主に以下の原因によるものです.
  • ストリームは、
  • を閉じる.
  • decodeStreamは
  • を2回呼び出した.
  • decodeStreamのBUG(本明細書では議論せず、詳細は参照)
  • この問題はとてもおもしろくて、ちょうど出会った時国内外で多くの異なる解決方法を見つけて、stackoverflowの上で質問の関連する問題(詳しくは参考の文章を参照して)もあって、本人は検証して総括した後にみんなと分かち合います.
  • ストリームが閉じられた解決策この問題が発生した主な原因は、ネットワークストリームを解析するコードがストリームが閉じた後に書かれていることであり、ストリームがいつ閉じられるかを分析するだけでよい.
  • decodeStreamは2回呼び出された問題の分析と解決方法本文は主にこの状況を分析する:まずこのような問題をどのように再現するか、明らかに画像の解像度を得るために、一般的にはinJustDecodeBoundsをtrueに設定し、画像を解析し、この時のdecodeStreamは必ずnullを返し、api自体の設計はこのようにして、
  • options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, options);

    しかし、上記のコードで次のようなコード、すなわちdecodeStreamメソッドを再度呼び出すと、返されるbitmapがnullとなるという問題が発生する.
    options.inJustDecodeBounds = false;
    Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);

    解像度decodeStreamを直接解析しないとBitmapオブジェクトに正常に戻る理由は簡単で、最初のdecodeStreamではinputstreamが操作されていたので、このときストリームの操作位置が移動し、再びdecodeStreamがストリームの開始位置から解析されないためBitmapオブジェクトは解析できません.次のコードを追加して、ストリームの読み書き位置を開始位置に復元するだけです.
    is.reset();

    これは,実際にはソースコードにストリームの読み出し位置の変化を考慮する必要があるという問題がある.
    個人的には、Bitmapの表示を最適化する必要がある以上、キャッシュを行う場合は、InputStreamネットワークストリームをファイルに書き込むことをお勧めしますが、decodeFileメソッドで解析すると上記の問題はありません.(decodeFile内部ではdecodeStreamを呼び出してローカルストリームを解析している)個人的には、ネット上でネットワークストリームを再読み込みするのは合理的ではなく、ユーザーのトラフィックを浪費するだけでなく、処理を遅くするだけでなく、ストリームを包装して再処理する個人的な感覚は、ローカルに書いて再解析するほうがいいと考えています.
    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;
            }
    
            // we need mark/reset to work properly
    
            if (!is.markSupported()) {
                is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);
            }
    
            // so we can call reset() if a given codec gives up after reading up to
            // this many bytes. FIXME: need to find out from the codecs what this
            // value should be.
            is.mark(1024);
    
        ...

    宣言
        ,    ,     。
         、      ,    。
        :[email protected]
    

    参考記事
    decodeStreamのBUG:http://endual.iteye.com/blog/1629549/stackoverflowでの議論:https://stackoverflow.com/questions/2503628/bitmapfactory-decodestream-returning-null-when-options-are-set