1. 程式人生 > >BitmapFactory.decodeStream方法返回null的錯誤分析

BitmapFactory.decodeStream方法返回null的錯誤分析

這個問題其實早就遇到了,由於停了幾天電無法工作,今天就把這問題記錄下分享下。利用BitmapFactory載入網路中的圖片時,使用decodeStream方法會返回null的錯誤。主要是由於下面幾個原因導致的:

  • 流已經關閉
  • decodeStream呼叫了兩次
  • decodeStream的BUG(本文不討論,詳見參考文章)

這個問題很有意思,剛開始遇到的時候在國內外到找到許多不同的解決方法,在stackoverflow上也有提問相關的問題(詳見參考文章),本人經過驗證總結後和大家分享下。

  • 流已經關閉的解決方法
    出現這個問題的主要原因是解析網路流的程式碼寫在了流關閉後,只需要分析清楚流在什麼時候關閉即可。

  • decodeStream呼叫了兩次的問題分析和解決方法
    本文主要對此情況進行分析:
    首先是如何重現這種問題,很顯然為了得到圖片的解析度,一般都會先把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]

參考文章

相關推薦

BitmapFactory.decodeStream方法返回null錯誤分析

這個問題其實早就遇到了,由於停了幾天電無法工作,今天就把這問題記錄下分享下。利用BitmapFactory載入網路中的圖片時,使用decodeStream方法會返回null的錯誤。主要是由於下面幾個原因導致的: 流已經關閉 decodeStream呼叫了兩次

小程式使用selectComponent獲取自定義元件時,返回null分析和解決方法

一、原因:        元件所在的佈局層級不同,該元件被建立的時間會有所不同,意味著ready(元件生命週期函式,元件佈局完成後執行)被呼叫的時間有所不同。由於元件建立完成的時間晚於頁面建立完成,即元件生命週期函式的ready被執行的時間晚於頁面生命週期

BitmapFactory.decodeStream方法及如何將Raw中的圖片載入為Bitmap

結論 將輸入流傳遞給 BitmapFactory.decodeStream(in) 方法,建立完成 Bitmap 之後,開發者一定要主動去關閉這個輸入流。否則,對輸入流執行 reset() 方法,則可以重新獲取輸入流中的所有資料,並且創建出一張新的圖片。 從res-raw目錄下獲取一張Bit

Android中GridView、ListView 的 getChildAt() 方法返回null 問題解釋

開發的Android app用到了GridView或者ListView,通常使用getChildAt(int position)方法獲取當前點選或者選中的View(即position對應的View)。   當ListView、GridView沒有滑動的時候,可以正常地獲

Spark troubleshooting 1運算元返回null錯誤 2錯誤持久化以及checkpoint

一、運算元返回為null 問題 在有些運算元函式裡,我們都需要有返回值。但是,有些可能不需要返回值,但是這時候不能直接返回null,返回null將會導致錯誤 Scala.Math(NULL) //異常 解決方法 如果不想有返回值,可以在返回的時候,返回一些特殊的值

執行Fragment的getActivity()方法返回null

在android開卡中Activity+ViewPager+Fragment幾乎是每一個專案中都會使用到的結構,在Fragment中如果需要使用到Context物件一般就是getActivity()。但是如果Activity被銷燬的話,getActivity()

Android中GridView、ListView 的 getChildAt() 方法返回null 問題

  開發的Android app用到了GridView或者ListView,通常使用getChildAt(int position)方法獲取當前點選或者選中的View(即position對應的View)。   當ListView、GridView沒有滑動的時候,可以正常地獲

Android BitmapFactory.decodeStream方法OutOfMemoryError 解決方法

我的Android App在執行下面程式碼時出現了OutOfMemoryError異常 image =BitmapFactory.decodeStream(assetManager.open(imgFilename)); App執行到這一步就會出現OOM異常,異常資訊如

Java呼叫Document.getElementById方法返回null的解決辦法

 Java中操作xml的函式Document.getElementById(String id),是通過指定的id來獲取對應的element。但是僅僅定義了正確的schema和對應的xml檔案是不夠的,返回值仍然是null。因為我們不僅要告訴xml檔案我們所用的schem

呼叫 BitmapFactory.decodeByteArray 函式返回 null

正確使用方法如下: Size previewSize = camera.getParameters().getPreviewSize(); YuvImage yuvimage=new YuvImage

安卓BitmapFactory.decodeStream()返回null的問題解決方法

今天遇到了一個問題,最終解決,記錄下解決方案: 問題:從網路獲取圖片,資料為InputStream流物件,然後呼叫BitmapFactory的decodeStream()方法解碼獲取圖片,返回null。 --------------------------------

BitmapFactory.decodeStream 返回值為null的問題

public void download(String u) throws Exception { URL url = new URL(u); HttpURLConnection conn = (HttpURLConnection) ur

訪問taotao-portal 中controller中返回taotaoresult 測試httppost方法 出現406錯誤

value 修改 resp word efault logs new nts blog   方案:1.檢查jackson包是否存在 @controller @RequestMapping(value = "/httpclient/post",method=Req

一個關於WCF調用遠程鏈接返回405錯誤不允許使用此方法的問題

問題 bin web format 地址欄 發現 nbsp 個人 spa 最近在調試WCF的接口時一直返回“405不允許使用此方法”,這個問題困擾了大半天,網上查了各種辦法,但是每個人遇到的問題不同還是不能解決。 最後無意之中發現問題所在,記錄一下幫助後面的同學解決問題。

vcpkg錯誤分析方法

使用 all http att 找到 發現 ros ash 信息 最近在使用vcpkg時,經常會碰到CMake錯誤。 有些以前能編譯通過的包, 過一段時間又不能編譯錯誤了。 錯誤提示一般是CMake錯誤, 弄得很郁悶。 我采用以下步驟解決了問題: 分析錯誤 查看錯誤日誌

windows server,nginx安裝,配置,運行nodeJS後端的web項目的實現,以及錯誤分析及解決方法

lease args app clu ali real-ip directory 很多 命令 如果對nodeJS的後端的系統,源代碼在github上,https://github.com/saucxs/nodeJSBlog ,如果覺得可以,請請star並fork項目 項目

cdh平臺Solr initialize failed錯誤分析與暴力解決方法

搭建好cdh平臺之後,不知道誤刪了什麼檔案,導致新增Solr服務時在初始化階段顯示Solr initialize failed,初始化失敗,重新安裝服務甚至多次重新安裝cdh平臺依然是這種狀況。檢視日誌顯示如下: 15/Sep/2018 18:52:53 +0000 org.

R語言-錯誤分析-Error in .Call.graphics(C_palette2, .Call(C_palette2, NULL)) : invalid graphics state

plot時,出現的錯誤01 > ggplot(religions_long, + aes(State, value, fill = variable)) + + geom_bar(stat = "identity") + + coord_flip()

【轉載++】C/C++錯誤分析errno,perror,strerror和GetLastError()函數返回錯誤代碼的意義

urn ali blog 查看 情況下 常見 ast mos 運行 本文是上一篇“fopen返回0(空指針NULL)且GetLastError是0”的側面回應。聽趕來多麽地正確和不容置疑,返回NULL時調用GetLastError來看看報錯啊,但當時卻返回了0,大家都覺得系

一些SAP UI5的控制元件無法按照預期渲染的錯誤分析方法和解決方案

我在index.html裡寫了下面這段程式碼: 'var oButton1 = new sap.m.Button({ text : "Button", tooltip : "This is a test tooltip",