Study on Android【五】–自訂ContentProvider的語義

來源:互聯網
上載者:User

Android做到現在。開始感覺到Android確實還是太年輕。系統本身好不夠成熟,相關文檔更是少的可憐。在Android的旅途中到處是暗坑陷阱,掉進去摔得半死,還只能靠自己琢磨著爬出來。

在大部分工作集中在了定義一套ContentProvider以及上層的顯示控制項上。一個ContentProvider向外提供的介面十分有限,但就是
這幾個東西你要表徵出正確(標準就是和系統ContentProvider一致的行為)的語義,還是很費功夫的。至少我就摔了好幾個跟頭。為了降低後續部
隊的傷亡,我努力搬走幾個絆腳石、填掉幾個坑,希望能有一些作用。
ContentProvider中,最重要的就是query操作。query根
據輸入返回一個合格Cursor。這就可能出現以下幾種情況:1. 查詢成功,包含幾個正確的結果;2. 查詢失敗,沒有符合的結果;3.
輸入錯誤, 觸發了某個異常;4.
沒能查詢到結果,但無法確定是輸入錯誤還是查詢失敗。第一種情況是我們最需要的,當然是需要正確維繫的,而最後一種情況在大部分應用中應該不會出現(但在
我的應用程式中會的*_#),而第二種第三種是比較常見的。
經過我的測試,系統的ContentProvider維持這樣的語義:如果是情況2,返回
正常的Cursor,並且,其count為0,相當於empty
cursor;如果是情況3,不拋出任何異常,返回null的Cursor。這樣的話明明白白寫出來是很好理解的,但由於沒有官方的文檔說明,在自訂的
時候經常會誤用。比如在某些情況下,用null表徵查詢失敗,用拋出異常來描述錯誤的輸入。
返回empty
cursor,如果是通過databasecursor自然會有db幫你維護,但是如果返回ArrayListCursor,MergeCursor或其
他自訂的Cursor,就需要自己維繫了。ArrayListCursor可以通過new ArrayListCursor(Columns,
new ArrayList(){})來提供。其中Columns一定不為null。MergeCursor不能以new
MergeCursor(new Cursor[]{})來建立,而需要通過new MergeCursor(new
Cursor[]{aEmptyCursor, ...}來維繫(其實很好理解,我呆了...)。自訂的Cursor也一定要提供產生empty
cursor的方式。
如果將ContentProvider作為一個單獨的module來理解,不通過異常而是通過null來返回MS是有好處
的。在module的出口吃掉所有異常,雖然不能提供足夠的資訊(異常資訊全部寫入日誌),但可能會使上層使用更簡單。但在Android中,我並沒有感
覺到這一點。作為ContentProvider的上層函數,ListActivity.managedQuery、
ListView.setListAdapter等,根本不能處理一個null的Cursor,在ListView中這會觸發一個異常。更無語的是,當你
把一個null Cursor設定為manage的後。它不會立即拋異常,而是在OnFreeze等生命週期函數的時候,因無法處理null
Cursor而拋出一個異常。這使得你根本無法在當地catch該異常,換句話,ListActivity的manageCursor根本是個無法使用的函數。你必須用getContext().query()獲得Cursor,然後判定該Cursor是否null,在進行startManagingCursor進行綁定。這遠不如直接用異常進行錯誤路徑的處理來的統一和方便。
當然,有些東西我們是不能改變的,只能去適應。對於自訂的cursor,
ContentProvider,最重要的,是在無人造錯誤輸入的情況下返回empty
cursor,而不是null。至於使用null響應還是異常響應上,我個人覺得還是和系統同步為好,雖然彆扭,但至少統一不容易有歧義。
此外,ContentProvider還有很多細緻的語義。比如返回的Cursor需要綁定一個URI,以便自動響應更新。自訂的更新需要支援deleteRow等操作語義等等。總之,我們需要更好的文檔或更多經驗文檔,以便我們更好的爬上巨人的肩膀。

PS:而上層的ListView,更是陷阱重重。首先綁定到ListView的Cursor必須有_id項,否則會有異常拋出。如果做過.net的開發,
這一點是可以想到的,但是,這種問題應該在文檔中寫明。另外,在ListView中,如果你不綁定一個資料來源,你一定不能在layout中添加涉及內容的
屬性。比如android:height="wrap_content",這會在onMeasure的時候拋出異常。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.