日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Study on Android【五】--自定义ContentProvider的语义

發(fā)布時(shí)間:2025/3/8 Android 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Study on Android【五】--自定义ContentProvider的语义 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Android做到現(xiàn)在。開(kāi)始感覺(jué)到Android確實(shí)還是太年輕。系統(tǒng)本身好不夠成熟,相關(guān)文檔更是少的可憐。在Android的旅途中到處是暗坑陷阱,掉進(jìn)去摔得半死,還只能靠自己琢磨著爬出來(lái)。
想 在大部分工作集中在了定義一套ContentProvider以及上層的顯示控件上。一個(gè)ContentProvider向外提供的接口十分有限,但就是 這幾個(gè)東西你要表征出正確(標(biāo)準(zhǔn)就是和系統(tǒng)ContentProvider一致的行為)的語(yǔ)義,還是很費(fèi)功夫的。至少我就摔了好幾個(gè)跟頭。為了降低后續(xù)部 隊(duì)的傷亡,我努力搬走幾個(gè)絆腳石、填掉幾個(gè)坑,希望能有一些作用。
ContentProvider中,最重要的就是query操作。query根 據(jù)輸入返回一個(gè)符合條件的Cursor。這就可能出現(xiàn)以下幾種情況:1. 查詢(xún)成功,包含幾個(gè)正確的結(jié)果;2. 查詢(xún)失敗,沒(méi)有符合的結(jié)果;3. 輸入錯(cuò)誤, 觸發(fā)了某個(gè)異常;4. 沒(méi)能查詢(xún)到結(jié)果,但無(wú)法確定是輸入錯(cuò)誤還是查詢(xún)失敗。第一種情況是我們最需要的,當(dāng)然是需要正確維系的,而最后一種情況在大部分應(yīng)用中應(yīng)該不會(huì)出現(xiàn)(但在 我的應(yīng)用中會(huì)的*_#),而第二種第三種是比較常見(jiàn)的。
經(jīng)過(guò)我的測(cè)試,系統(tǒng)的ContentProvider維持這樣的語(yǔ)義:如果是情況2,返回 正常的Cursor,并且,其count為0,相當(dāng)于empty cursor;如果是情況3,不拋出任何異常,返回null的Cursor。這樣的話(huà)明明白白寫(xiě)出來(lái)是很好理解的,但由于沒(méi)有官方的文檔說(shuō)明,在自定義的 時(shí)候經(jīng)常會(huì)誤用。比如在某些情況下,用null表征查詢(xún)失敗,用拋出異常來(lái)描述錯(cuò)誤的輸入。
返回empty cursor,如果是通過(guò)databasecursor自然會(huì)有db幫你維護(hù),但是如果返回ArrayListCursor,MergeCursor或其 他自定義的Cursor,就需要自己維系了。ArrayListCursor可以通過(guò)new ArrayListCursor(Columns, new ArrayList(){})來(lái)提供。其中Columns一定不為null。MergeCursor不能以new MergeCursor(new Cursor[]{})來(lái)創(chuàng)建,而需要通過(guò)new MergeCursor(new Cursor[]{aEmptyCursor, ...}來(lái)維系(其實(shí)很好理解,我呆了...)。自定義的Cursor也一定要提供生成empty cursor的方式。
如果將ContentProvider作為一個(gè)單獨(dú)的module來(lái)理解,不通過(guò)異常而是通過(guò)null來(lái)返回MS是有好處 的。在module的出口吃掉所有異常,雖然不能提供足夠的信息(異常信息全部寫(xiě)入日志),但可能會(huì)使上層使用更簡(jiǎn)單。但在Android中,我并沒(méi)有感 覺(jué)到這一點(diǎn)。作為ContentProvider的上層函數(shù),ListActivity.managedQuery、 ListView.setListAdapter等,根本不能處理一個(gè)null的Cursor,在ListView中這會(huì)觸發(fā)一個(gè)異常。更無(wú)語(yǔ)的是,當(dāng)你 把一個(gè)null Cursor設(shè)置為manage的后。它不會(huì)立即拋異常,而是在OnFreeze等生命周期函數(shù)的時(shí)候,因無(wú)法處理null Cursor而拋出一個(gè)異常。這使得你根本無(wú)法在當(dāng)?shù)豤atch該異常,換句話(huà),ListActivity的manageCursor根本是個(gè)無(wú)法使用的函數(shù)。你必須用getContext().query()獲得Cursor,然后判定該Cursor是否null,在進(jìn)行startManagingCursor進(jìn)行綁定。這遠(yuǎn)不如直接用異常進(jìn)行錯(cuò)誤路徑的處理來(lái)的統(tǒng)一和方便。
當(dāng)然,有些東西我們是不能改變的,只能去適應(yīng)。對(duì)于自定義的cursor, ContentProvider,最重要的,是在無(wú)人造錯(cuò)誤輸入的情況下返回empty cursor,而不是null。至于使用null響應(yīng)還是異常響應(yīng)上,我個(gè)人覺(jué)得還是和系統(tǒng)同步為好,雖然別扭,但至少統(tǒng)一不容易有歧義。
此外,ContentProvider還有很多細(xì)致的語(yǔ)義。比如返回的Cursor需要綁定一個(gè)URI,以便自動(dòng)響應(yīng)更新。自定義的更新需要支持deleteRow等操作語(yǔ)義等等。總之,我們需要更好的文檔或更多經(jīng)驗(yàn)文檔,以便我們更好的爬上巨人的肩膀。

PS:而上層的ListView,更是陷阱重重。首先綁定到ListView的Cursor必須有_id項(xiàng),否則會(huì)有異常拋出。如果做過(guò).net的開(kāi)發(fā), 這一點(diǎn)是可以想到的,但是,這種問(wèn)題應(yīng)該在文檔中寫(xiě)明。另外,在ListView中,如果你不綁定一個(gè)數(shù)據(jù)源,你一定不能在layout中添加涉及內(nèi)容的 屬性。比如android:height="wrap_content",這會(huì)在onMeasure的時(shí)候拋出異常。

轉(zhuǎn)載于:https://blog.51cto.com/duguguiyu/362200

總結(jié)

以上是生活随笔為你收集整理的Study on Android【五】--自定义ContentProvider的语义的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。