Android開發筆記之:深入理解Cursor相關的效能問題

來源:互聯網
上載者:User

當資料庫中存有大量資料的時候,用Cursor查詢時要注意,有可能引發效能問題。資料庫查詢出來的Cursor都會由一個CursorWindow來進行資料管理,包括記憶體空間的申請和資料的填充。CursorWindow對Cursor中的內容大小有限制,限制為1024*1024也就是1M,換句話說Cursor中資料的大小不能超過1M,如果超過1M會引發如下的錯誤:

複製代碼 代碼如下:08-23 05:48:31.838: DEBUG/Cursor(1805): skip_rows row 149
08-23 05:48:31.844: ERROR/CursorWindow(1805): need to grow: mSize = 1048576, size = 11499, freeSpace() = 7397, numRows = 80
08-23 05:48:31.844: ERROR/CursorWindow(1805): not growing since there are already 80 row(s), max size 1048576
08-23 05:48:31.844: ERROR/Cursor(1805): Failed allocating 11499 bytes for blob at 228,7
08-23 05:48:31.849: DEBUG/Cursor(1805): finish_program_and_get_row_count row 12
08-23 05:48:31.851: DEBUG/browser/BrowserBookmarkFoldersAdapter(1805): getView()-Position:149
08-23 05:48:32.019: DEBUG/Cursor(1805): skip_rows row 148

這表明CursorWindow中的空閑空間已經不足,已經在申請新的空間,但似乎申請失敗。這個錯誤有時候會導致查詢得到的Cursor為null,有時候不會引發太嚴重的問題。但是它會引起效能上的問題,不停的申請空間會佔用大量的CPU時間,從而導致整個手機變卡。特別是在ListView或GridView中綁定的Cursor,會導致無法滑動,或者滑動變的十分的卡。用Android2.3的原生Browser,開啟其中的記錄,當有超過200條記錄時,不停的滑動,特別是由下向上滑時會變的十分的卡,而對於其書籤,如果條目超過100,且每個都有縮圖時,滑動會變得特別的卡,甚至都打不開,就是這個原因。
這個問題沒有根本的解法,這是Android系統的限制,唯一可行的就是想辦法避免,也就是儘可能讓Cursor的大小 小於1M,以下是可行的方法:
1. 只查詢需要的欄位
這個特別重要,根據UI顯示的需要,或者實際的需要查詢需要的欄位。就是一定要給ContentResolver.query(uri, projection)第二個參數PROJECTION,如果這個參數為null,那麼就會查詢表中所有的欄位,那麼當條數一增加Cursor的大小 會增長很快。Browser中記錄的原因就是它在query的時候查詢了所有的欄位,其數所庫中儲存了favicon和thumbnail二進位檔案,因此當包含了這二個欄位時,Cursor的容量很容易就達到了限制。
2. 二進位檔案不要存在資料庫中
資料庫僅適用於儲存一些較短文字,整數,布爾,浮點數等一些,易於查詢和操作的輕量級的資料,目的也是在於快速搜尋和查詢。對於像圖片,較長的文字(如文章)等大資料,最好直接以檔案形式儲存在硬碟中,然後在資料庫儲存它們的訪問路徑。對於像favicon這樣的小圖片也可以考慮存在資料庫中,但是像對於thumbnail的圖片就不明智,除非整個應用在數量上有限制(比如只有幾十或百級)否則很容易在查詢的時候達到1M的限制。
3. 對於特別大量的資料超過5000級或萬級或十萬級或百萬級的要分段查詢
無論表中的一條記錄資料量如何的小,當條數達到5000級或者萬級或者更多的時候,還是會達到1M的限制,這時就需要分段查詢,比如每次查詢500個,或者1000個。另外,如果是要做展示用,這麼多資料一下子出來,使用者也不方便查看。
【執行個體】Android2.3書籤,記錄和最多訪問三個頁面當資料量達到300左右時,就會出現滑動很卡的現象,特別是由下向上滑動時,特別的卡,會狂打出:複製代碼 代碼如下:08-23 05:48:31.844: ERROR/CursorWindow(1805): need to grow: mSize = 1048576, size = 11499, freeSpace() = 7397, numRows = 80
08-23 05:48:31.844: ERROR/CursorWindow(1805): not growing since there are already 80 row(s), max size 1048576
08-23 05:48:31.844: ERROR/Cursor(1805): Failed allocating 11499 bytes for blob at 228,7

這樣的LOG。而書籤似乎都沒有辦法開啟和滑動,其特別的卡。
究其原因就是它們在查詢的時候都用了同一個欄位集Browser.HISTORY_PROJECTION這個是把bookmarks表中的所有欄位都 查詢出來。書籤,記錄和最多訪問雖是三個不同的展示頁,但它們的資料是相同的都是來自bookmarks表。Bookmarks表中存有_id,title,url,bookmark,favicon,touch_icon,thumbnail等欄位,其中favicon和thumbnail是二進位圖片資料(byte[])。Browser.HISTORY_PROJECTION裡麵包含了所有的欄位,當然也包含了favicon和thumbnail,所以當條目一旦達到200多時,Cursor就會達到其1M的限制,因此會導致效能下降,滑動變卡。

事實上對於記錄和最多訪問二個頁面來講thumbnail和touch_icon根本就沒有用到,它只需要_id,title,url,bookmark和favicon;對於書籤頁,也僅是在GRID時才用到thumbnail。所以,只需要把查詢時的欄位集Browser.HISTORY_PROJECTION中的THUMBNAIL去掉,即可以解決滑動變卡。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.