




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、精選優(yōu)質(zhì)文檔-傾情為你奉上Android學(xué)習(xí)心得 - 計(jì)算機(jī)應(yīng)用(1) 張峰1.關(guān)于Activity1. 在一個(gè)Activity中使用多個(gè)View如果把Activity看作MVC中的Control?它負(fù)責(zé)管理UI和接受事件(包括用戶的輸入),雖然說一個(gè)Activity通常對應(yīng)一個(gè)屏幕,但事實(shí)上,我們是可以只用一個(gè)Activity管理多個(gè)不同的View來實(shí)現(xiàn)簡單的邏輯。首先,我們增加一個(gè)新的描述layout/second.xml。除了一個(gè)“Hello中國”以外,增加一個(gè)按鈕可以返回前一個(gè)界面。然后,在代碼中我們要為helloTwo增加兩個(gè)方法,setViewOneCommand和setViewT
2、woCommand,分別處理一下在不同界面時(shí),從資源里加載組件并為組件綁定一個(gè)事件處理器最后,我們需要在onCreate的時(shí)候,也就是啟動(dòng)后的main界面上設(shè)置一下按鈕事件處理器。2. 還是回到正道上,多個(gè)Activity之間的跳轉(zhuǎn)Android中提供一個(gè)叫Intent的類來實(shí)現(xiàn)屏幕之間的跳轉(zhuǎn),按文檔的說法,似乎他們也建議采用這種方法,Intent的用法比較復(fù)雜,現(xiàn)在我先看看它最簡單的用法。這里的跳轉(zhuǎn)用Intent來操作,它的最簡單用法就是用函數(shù)setClass()設(shè)置跳轉(zhuǎn)前后兩個(gè)Activity類的實(shí)例,然后調(diào)用Activity自己的startActivity(intent)即可。最后一句f
3、inish()表示將當(dāng)前Activity關(guān)掉(如果不關(guān)掉會(huì)如何?你可以自己試一下看,事實(shí)上有時(shí)我們是不需要關(guān)掉當(dāng)前Activity的)。然后,我們同樣弄一個(gè)Activity類HelloThreeB,代碼與前面的差不多,只是將setClass的兩個(gè)參數(shù)反一下,這樣就可以簡單地實(shí)現(xiàn)在兩個(gè)Activity界面中來回切換的功能了。2.關(guān)于 Intent的使用Intent分為兩大類,顯性的(Explicit )和隱性的(Implicit)。一般來說,intent要定位事件的目的地,無外乎需要以下幾個(gè)信息:1.種類(category),比如我們常見的 LAUNCHER_CATEGORY 就是表示這是一類應(yīng)
4、用程序。2.類型(type),在前面的例子中沒用過,表示數(shù)據(jù)的類型,這是隱性Intent定位目標(biāo)的重要依據(jù)。3.組件(component),前面的例子中用的是setClass,不過也可以用setComponent來設(shè)置intent跳轉(zhuǎn)的前后兩個(gè)類實(shí)例。4.附加數(shù)據(jù)(extras),在ContentURI之外還可以附加一些信息,它是Bundle類型的對象。其實(shí),如果是在一個(gè)應(yīng)用內(nèi)部,這種隱性的intent實(shí)在有點(diǎn)別扭,個(gè)人覺得,這種松藕合的實(shí)現(xiàn)方法,只適用于那些較大的系統(tǒng)或者多個(gè)不同的應(yīng)用之間的調(diào)用,可手機(jī)上又有什么“較大”的系統(tǒng)呢?無非是可以與不同來源的多個(gè)應(yīng)用之間方便地互操作而已,那么會(huì)是什
5、么樣的場景呢?比如,給QQ好友發(fā)送gmail郵件,用GoogleMap查找QQ好友所在的位置?看上去挺不錯(cuò)的。關(guān)于這個(gè)ContentProvider,其實(shí)還有話說,它主要是的那些看似數(shù)據(jù)庫操作的方法我們都沒真正去實(shí)現(xiàn)呢。不過今天就到這里了,等下回再去研究吧。3.關(guān)于ListActivity準(zhǔn)備一個(gè)List對象并借助Adapter就可以構(gòu)造出一個(gè)列表。重載onListItemClick方法可以響應(yīng)選擇事件,利用第一個(gè)參數(shù)可以訪問到這個(gè)ListView實(shí)例以得到選中的條目信息。這里有一點(diǎn)要說明的,就是如果更簡單的話,其實(shí)連那個(gè)setContentView都可以不要了,Android也會(huì)自動(dòng)幫我們構(gòu)
6、造出一個(gè)全屏的列表。但是本例中我們需要一個(gè)TextView來顯示選中的條目,所以我們需要一個(gè)layout.mainb描述一下這個(gè)列表窗口。這里需要注意的是那個(gè)ListView的ID,是系統(tǒng)自定義的android:list,不是我們隨便取的,否則系統(tǒng)會(huì)說找不到它想要的listview了。然后,在這個(gè)listview之外,我們又增加了一個(gè)TextView,用來顯示選中的條目。再來說說這里用到的ArrayAdapter,它的構(gòu)造函數(shù)中第二個(gè)參數(shù)是一個(gè)資源ID,ArrayAdapter的API文檔中說是要求用一個(gè)包含TextView的layout文件,平臺(tái)用它來顯示每個(gè)選擇條目的樣式,這里的取值是R.
7、layout.list_row,所以,我們還有一個(gè)list_row.xml文件來描述這個(gè)布局,相當(dāng)簡單。從ArrayAdapter上溯到BaseAdapter,發(fā)現(xiàn)還有幾個(gè)同源的Adapter也應(yīng)該可以使用,象SimpleAdapter和CursorAdapter,還是做個(gè)例子來實(shí)驗(yàn)一下吧。然后,在HelloTwoB中的onCreate函數(shù)中,修改代碼,有幾個(gè)不同:items的元素是HashMap實(shí)例,這是一點(diǎn)變化,然后構(gòu)造函數(shù)除了要求items以外,還要求提供一個(gè)string來說明用hash表中的哪個(gè)字段顯示在列表中,而后是一個(gè)資源ID的數(shù)組。因?yàn)閱渭兊腃ursorAdapter是抽象類,所
8、以我用的是它的子類SimpleCursorAdapter,很好理解,先用ContentResolver查詢通訊簿得到一個(gè)游標(biāo),然后告訴SimpleCursorAdapter要用其中的People.NAME作為顯示項(xiàng)來構(gòu)造出一個(gè)adapter即可。4.關(guān)于Dialog 注意到android.app包下除了Dialog(可用于制作復(fù)雜的對話框)以外,還包括了幾個(gè)系統(tǒng)定義好的對話框類,如DatePickerDialog、TimePickerDialog及AlertDialog。其中AlertDialog我上回用過一次,基本上就那樣子了,今天看看另外兩個(gè)對話框的使用吧。很簡單的,無非是需要一個(gè)OnDa
9、teSetListener接口的實(shí)現(xiàn)而已,在它里面的dateSet方法中就可以得到選擇的日期了。而TimePickerDialog與DatePickerDialog使用如出一轍??纯戳硪粋€(gè)ProgressDialog的用法吧,這個(gè)類與AlertDialog一樣包含了多個(gè)static的方法,所以使用起來是非常方便的。比如說,如果我們需要用它來表示一個(gè)長時(shí)間的操作。5.關(guān)于Service和Notification大略地看了一下android.app下的Service類,覺得它與Activity非常相似,只是要注意幾個(gè)地方:1.生命周期,Service的從onCreate()->onStart
10、(int,Bundle)->onDestroy()顯得更為簡單。但是它的onStart是帶參數(shù)的,第一個(gè)ID可用來標(biāo)識(shí)這個(gè)service,第二個(gè)參數(shù)顯示是用來傳遞數(shù)據(jù)的了。比較Activity,傳遞數(shù)據(jù)的Bundle是在onCreate就帶進(jìn)入的。2.Service的啟動(dòng)由Context.startService開始,其實(shí)Activity或者Service都是Context的派生類。結(jié)束于Context.stopService()或者它自己的stopSelf()。3.Service還有一個(gè)與Activity不一樣的是它可以由另一個(gè)Context去綁定一個(gè)已存在的Service。就是這個(gè)方
11、法Context.bindService(),被綁定的Service要求是已經(jīng)onCreate了但可以沒有onStart。在Service類中有個(gè)抽象方法getBinder()可以得到這個(gè)IBinder對象。關(guān)于這方面的細(xì)節(jié),以后再看,這里只做個(gè)記錄罷。4.與Service有關(guān)的還有一個(gè)安全的問題,可以在Manifest.xml中用<uses-permission>標(biāo)簽來聲明一個(gè)Service的訪問權(quán)限,關(guān)于的安全問題也留待以后再解決吧。6GridView與ImageView簡單一點(diǎn)吧,就瞧瞧那個(gè)Grid的效果,提供了一個(gè)GridView,不過從APIDemo中看來,它似乎與PC上
12、的GRID差別還是挺大的,更像那個(gè)IconView的感覺。不知道中如何實(shí)現(xiàn)表格界面?雖然在移動(dòng)終端上,表格一般不會(huì)有誰使用,大家似乎更傾向于使用ListView,而Android對于ListView則有更簡單的實(shí)現(xiàn)ListActivity。很簡單,只要重載幾個(gè)方法就可以了,關(guān)鍵是那個(gè)getView方法,它負(fù)責(zé)構(gòu)建出每個(gè)單元格中的對象實(shí)例。這里我們構(gòu)造的是一個(gè)ImageView實(shí)例。然后就是同樣的將這個(gè)Adapter賦給GridView即可,大家可以看看效果,注意在做這個(gè)例子前,先放幾個(gè)小圖片到res/drawable目錄下,buildproject一下就可以得到那個(gè)R.drawable.a了(
13、這里的a是圖像文件名,如a.png)。在getView方法中我們使用了ImageView類,這又是一個(gè)widget。除了上面用到的幾個(gè)方法以外,還有以下幾個(gè)方法值得注意:與圖像來源有關(guān)的方法,我們只用了資源文件的方式。還是習(xí)慣性跑題了,其實(shí),我是想通過我對這個(gè)類的無數(shù)次Debugger跟進(jìn),說說它的多線程異步處理的解決策略的。他的基本策略如下:1. 當(dāng)你實(shí)例化一個(gè)AsyncQueryHandler類時(shí)(包括其子類.),它會(huì)單件構(gòu)造一個(gè)線程(后面會(huì)詳述.),這個(gè)線程里面會(huì)構(gòu)建一個(gè)消息循環(huán)。2. 獲得該消息循環(huán)的指針,用它做參數(shù)實(shí)例化另一個(gè)Handler類,該類為內(nèi)部類。至此,就有了兩個(gè)線程,各自
14、有一個(gè)Handler來處理消息。3. 當(dāng)調(diào)用onXXX的時(shí)候,在XXX函數(shù)內(nèi)部會(huì)將請求封裝成一個(gè)內(nèi)部的參數(shù)類,將其作為消息的參數(shù),將此消息發(fā)送至另一個(gè)線程。4. 在該線程的Handler中,接受該消息,并分析傳入的參數(shù),用初始化時(shí)傳入的ContentResolver進(jìn)行XXX操作,并返回Cursor或其他返回值。5. 構(gòu)造一個(gè)消息,將上述返回值以及其他相關(guān)內(nèi)容綁定在該消息上,發(fā)送回主線程。6. 主線程默認(rèn)的AsyncQueryHandler類的handleMessage方法(可自定義,但由于都是內(nèi)部類,基本沒有意義.)會(huì)分析該消息,并轉(zhuǎn)發(fā)給對應(yīng)的onXXXComplete方法。7. 用戶重寫的
15、onXXXComplete方法開始工作。這就是它偷偷摸摸做過的事情,基本還是很好理解的。我唯一好奇的是它的線程管理方式,我猜測他是用的單件模式。第一個(gè)AsyncQueryHandler的實(shí)例化會(huì)導(dǎo)致創(chuàng)建一個(gè)線程,從此該線程成為不死老處男,所有的ContentResolver相關(guān)的工作,都由該線程統(tǒng)一完成。個(gè)人覺得這種解決方式很贊。本來這個(gè)線程的生命周期就很難估量,并且,當(dāng)你有一個(gè)ContentProvider的請求的時(shí)候,判斷你會(huì)做更多的類似操作并不過分。就算錯(cuò)了,花費(fèi)的也只是一個(gè)不死的線程(與進(jìn)程同生死共存亡.),換來的卻是簡單的生命周期管理和無數(shù)次線程生死開銷的節(jié)約。同時(shí)另外一個(gè)很重要的問
16、題,他并會(huì)涉及到單件中數(shù)據(jù)同步的問題,每個(gè)類都有各自的Handler類,彼此互不干擾,分發(fā)可以分別進(jìn)行。當(dāng)多個(gè)數(shù)據(jù)請求的時(shí)候,在同一個(gè)ContentResolver上進(jìn)行的可能微乎其微,這就避免了堵塞??偠灾@套解決辦法和Android的整體設(shè)計(jì)算是天作之合了。所以建議,如果你有什么非ContentProvider操作,卻需要異步多線程執(zhí)行的話,模擬一套,是個(gè)不錯(cuò)的策略,當(dāng)然,具體情況具體分析,生搬硬套是學(xué)不好馬列主義的。7.顯示控件使用的界面顯示同樣也是基于控件的。通常是用View(包括ViewGroup)控件配上XML的樣式來做的。具體細(xì)節(jié)不想說了,可以參考 Samples里的ApiD
17、emos/View,和View的Doc,以及Implementing a UI這篇Doc。其他還有很多,感覺算是SDK講述的最多的內(nèi)容。從控件的使用上,和網(wǎng)頁的設(shè)計(jì)類似,盡量用parent_width之類的抽象長度,用Theme來做風(fēng)格,抽取所有的字串等信息做本地化設(shè)計(jì)。相關(guān)內(nèi)容參看Implementing a UI就好。一類比較重要的是數(shù)據(jù)綁定控件。如果做過ASP.Net會(huì)從中看到很多類似的地方。一個(gè)支持?jǐn)?shù)據(jù)綁定的控件,比如ListView??梢酝ㄟ^一個(gè) ListAdapter綁定到一個(gè)數(shù)據(jù)源上。ListAdapter是一個(gè)抽象類,主要的實(shí)現(xiàn)類包括SimpleAdapter和 SimpleC
18、ursorAdapter。前者是綁定一個(gè)靜態(tài)的Array,后者是綁定一個(gè)動(dòng)態(tài)的Cursor。Cursor前面說過,是一個(gè)指向數(shù)據(jù)源的隨機(jī)迭代器,將View綁定到Cursor通常要設(shè)置這樣幾個(gè)參數(shù)。一個(gè)是每一行的樣式,稱作Row Layout,其實(shí)就是一個(gè)普通的Layout的XML文件。還有就是一個(gè)列和現(xiàn)實(shí)控件的對應(yīng)關(guān)系。那個(gè)控件顯示哪個(gè)列的值,這是需要配置的。為了定制一個(gè)良好的數(shù)據(jù)顯示控件,最簡單你可以定制很PP的Row Layout,復(fù)雜一點(diǎn)就是可以重載綁定控件View,或者是適配器ListAdapter。如果是一個(gè)數(shù)據(jù)顯示密集的應(yīng)用,且你對UI有些追求,這個(gè)工作估計(jì)是必不可少的。一個(gè)主要用
19、于顯示數(shù)據(jù)內(nèi)容的Activity,可以選擇派生自ListActivity。它提供了一個(gè)具有ListView 的Layout,還有simple_list_item_1, simple_list_item_2, two_line_list_item等默認(rèn)的Row Layout,還有一些比較不錯(cuò)的API,和可供響應(yīng)選擇Item的事件??梢詽M足你比較基礎(chǔ)的需求。如果你覺得只有一個(gè)ListView的界面太突兀,你可以為這個(gè)ListActivity指定一個(gè)Layout,需要注意的是,你需要提供一個(gè)id為android:id/list的ListView控件,避免Activity在內(nèi)部偷偷尋找該控件的時(shí)候失敗
20、。除了這些要求,做好UI還有注意易用性和效率??旖萱I是一個(gè)比較不錯(cuò)的選擇,在 Activity中調(diào)用setDefaultkeyMode(SHORTCUT_DEFAULT_KEYS),可以開啟快捷鍵模式,然后你可以將菜單綁定到指定快捷鍵上就OK了。個(gè)人覺得Tip也是一個(gè)比較重要的東西,但目前觀察看來,這個(gè)東西只能夠自己提供了。界面的動(dòng)態(tài)性有時(shí)候是不可避免的,比如說菜單就是一個(gè)需要經(jīng)常根據(jù)光標(biāo)位置提供不同的選項(xiàng)。這個(gè)東西很人道的考慮到了,你可以參看NodeList這個(gè)Sample。它采取的應(yīng)該是一個(gè)靜態(tài)模擬動(dòng)態(tài)的方式,這樣有助于提高速度。你也可以利用ViewInflate,動(dòng)態(tài)從一個(gè)XML創(chuàng)建一個(gè)
21、控件。成本據(jù)Doc說很大,不到萬不得已不要使用。8.Intent消息傳遞在前面寫的ContentProvider時(shí)候,可以看到那是基于觀察者模式的一個(gè)消息傳遞方法。每一個(gè)Cursor、ContentResolver做為一個(gè)小的注冊中心,相關(guān)觀察者可以在這個(gè)中心注冊,更新消息由注冊中心分發(fā)給各個(gè)觀察者。而在MFC或Winform中,都會(huì)形成一個(gè)消息網(wǎng),讓消息在網(wǎng)中流動(dòng),被各節(jié)點(diǎn)使用、吃掉或者在出口死掉。相比之下,我個(gè)人覺得基于Intent的核心消息傳遞機(jī)制是有所不同的。它應(yīng)該會(huì)有一個(gè)全局性的注冊中心,這個(gè)注冊中心是隱性的,整個(gè)系統(tǒng)中就那么一個(gè)。所有的消息接收者,都被隱形的注冊到這個(gè)中心。包括Ac
22、tivity,Service和IntentReceiver。其實(shí)說隱形注冊是不確切的,所有注冊都還是我們手動(dòng)告訴注冊中心的,只是與傳統(tǒng)的方式不一樣,我們通常不是通過代碼,而是通過配置文件來做。在應(yīng)用的Manifest中,我們會(huì)為一些Activity或Service添加上Intent-filter,或在配置文件中添加<receiver></receiver>項(xiàng)。這其實(shí)就相當(dāng)于向系統(tǒng)的注冊中心,注冊了相關(guān)的Intent-filter和receiver(這個(gè)事情完全可以通過代碼來做,只是這樣就失去了修改的靈活性)。當(dāng)程序有一個(gè)消息希望發(fā)出去的時(shí)候,它需要將消息封裝成一個(gè)Int
23、ent,并發(fā)送。這時(shí)候,應(yīng)該是有一個(gè)統(tǒng)一的中心(恩,有可能Android底層實(shí)現(xiàn)的時(shí)候不是,但簡單這樣看是沒問題的.)接受到這個(gè)消息,并對它進(jìn)行解析、判定消息類型(這個(gè)步驟降低了耦合.),然后檢查注冊了相匹配的filter或receiver,并創(chuàng)建或喚醒接收者,將消息分發(fā)給它。這樣做有很多好處。雖然這種傳遞有的時(shí)候不如點(diǎn)對點(diǎn)的傳遞快(這有些需要速度的地方,我們看到Android會(huì)通過直接通信來做),但有時(shí)候又因?yàn)樗唤?jīng)過一跳(姑且這么叫吧.),比復(fù)雜的流動(dòng)又要更快。更重要的是,它耦合性低,在手機(jī)平臺(tái)這種程序組件多變的條件下使用十分適合。并且它可以很容易實(shí)現(xiàn)消息的精確或模糊匹配,彈性很大。(我個(gè)
24、人曾想在開發(fā)一個(gè)C+二次平臺(tái)的時(shí)候引入這樣的機(jī)制,但在C+中,建立一套完整的數(shù)據(jù)marshal機(jī)制不容易,相比之下,用java來做會(huì)簡單很多.)恩,廢話說了很多,具體講講Android中Intent的使用。當(dāng)你有一個(gè)消息需要傳遞,如果你明確知道你需要哪個(gè)Activity或者其他Class來響應(yīng)的話,你可以指定這個(gè)類來接受該消息,這被稱為顯性發(fā)送。你需要將Intent的class屬性設(shè)置成目標(biāo)。這種情況很常見,比如startActivity的時(shí)候,會(huì)清楚當(dāng)前Activity完了應(yīng)該是哪個(gè)Activity,那就明確的發(fā)送這個(gè)消息。但是,有的時(shí)候你并不確定你的消息是需要具體哪個(gè)類來執(zhí)行,而只是知道接
25、收者該符合哪些條件。比如你只需要有一個(gè)接收者能顯示用戶所選的數(shù)據(jù),而不想制定某個(gè)具體的方法,這時(shí)候你就需要用到隱形發(fā)送(傳統(tǒng)上,我們可能會(huì)考慮用多態(tài),但顯然這種方式更為靈活.)。在Android中,你可以為Intent指定一個(gè)action,表示你這個(gè)指令需要處理的事情。系統(tǒng)為我們定義了很多Action類型,這些類型使系統(tǒng)與我們通信的語言(比如在Activity里面加一個(gè)Main的filter,該activity就會(huì)做成該應(yīng)用的入口點(diǎn)),當(dāng)然你也可以用于你自己的應(yīng)用之間的通信(同樣當(dāng)然,也可以自定義.)。強(qiáng)烈建議,在自己程序接收或發(fā)出一個(gè)系統(tǒng)action的時(shí)候,要名副其實(shí)。比如你響應(yīng)一個(gè)view
26、動(dòng)作,做的確實(shí)edit的勾當(dāng),你發(fā)送一個(gè)pick消息,其實(shí)你想讓別人做edit的事,這樣都會(huì)造成混亂。當(dāng)然只有Action有時(shí)候是不夠的,在Android中我們還可以指定catalog信息和type/data信息,比如所有的顯示數(shù)據(jù)的Activity,可能都會(huì)響應(yīng)View action。但很多與我們需要顯示的數(shù)據(jù)類型不一樣,可以加一個(gè)type信息,明確的指出我們需要顯示的數(shù)據(jù)類型,甚至還可以加上一個(gè)catalog信息,指明只有你只有按的是“中鍵”并發(fā)出這樣的消息才響應(yīng)。從上面可以看出,Android的Intent可以添加上class, action, data/type, catalog等消息
27、,注冊中心會(huì)根據(jù)這些信息幫你找到符合的接收者。其中class是點(diǎn)對點(diǎn)的指示,一旦指明,其他信息都被忽略。Intent中還可以添加key/value的數(shù)據(jù),發(fā)送方和接收方需要保持統(tǒng)一的key信息和value類型信息,這種數(shù)據(jù)的marshal在java里做,是不費(fèi)什么力氣的。Android的Intent發(fā)送,可以分成單播和廣播兩種。廣播的接收者是所有注冊了的符合條件的IntentReceiver。在單播的情況下,即使有很多符合條件的接收者,也只要有一個(gè)出來處理這個(gè)消息就好(恩,個(gè)人看法,沒找到確切條款或抉擇的算法,本來想實(shí)驗(yàn)一下,沒來得及.),這樣的情況很容易理解,當(dāng)你需要修改某個(gè)數(shù)據(jù)的時(shí)候,你肯
28、定不會(huì)希望有十個(gè)編輯器輪流讓你來處理。當(dāng)廣播不是這樣,一個(gè)receiver沒有辦法阻止其他receiver進(jìn)行對廣播事件的處理。這種情況也很容易理解,比如時(shí)鐘改變了,鬧鐘、備忘錄等很多程序都需要分別進(jìn)行處理。在自己的程序的使用中,應(yīng)該分清楚區(qū)別,合理的使用。9.ContentProvider數(shù)據(jù)模型數(shù)據(jù)庫操作從我目前掌握的知識(shí)來看,SQLite比較輕量(沒有存儲(chǔ)過程之類的繁雜手段),用起來也比較簡單。實(shí)例化一個(gè)SQLiteDatabase類對象,通過它的APIs可以搞定大部分的操作。從sample中看,Android中對db的使用有一種比較簡單的模式,即派生一個(gè) ContentProvider
29、DatabaseHelper類來進(jìn)行SQLiteDatabase對象實(shí)例的獲取工作?;旧?, ContentProviderDatabaseHelper類扮演了一個(gè)singleton的角色,提供單一的實(shí)例化入口點(diǎn),并屏蔽了數(shù)據(jù)庫創(chuàng)建、打開升級(jí)等細(xì)節(jié)。在ContentProvider中只需要調(diào)用ContentProviderDatabaseHelper的openDatabase方法獲取SQLiteDatabase的實(shí)例就好,而不需要進(jìn)行數(shù)據(jù)庫狀態(tài)的判斷。URI像進(jìn)行數(shù)據(jù)庫操作需要用SQL一樣,對ContentProivder進(jìn)行增刪改查等操作都是通過一種特定模式的URI來進(jìn)行的(ig:conte
30、nt: /provider/item/id),URI的能力與URL類似,具體細(xì)節(jié)可以查看SDK。建立自己的ContentProvider,只需要派生 ContentProivder類并實(shí)現(xiàn)insert, delete, update等抽象函數(shù)即可。在這些接口中比較特殊的是getType(uri)。根據(jù)傳入的uri,該方法按照MIME格式返回一個(gè)字符串(=!沒聽過的詭異格式.)唯一標(biāo)識(shí)該uri的類型。所謂uri的類型,就是描述這個(gè)uri所進(jìn)行的操作的種類,比如content:/xx/a與 content:/xx/a/1不是一個(gè)類型(前者是多值操作,后者是單值),但content:/xx/a/1和
31、content:/xx/a/2 就會(huì)是一個(gè)類型(只是id號(hào)不同而已)。在ContentProvider通常都會(huì)實(shí)例化一個(gè)ContentURIPraser來輔助解析和操作傳入的URI。你需要事先(在static域內(nèi))為該ContentURIPraser建立一個(gè)uri的語法樹,之后就可以簡單調(diào)用 ContentURIPraser類的相關(guān)方法進(jìn)行uri類型判斷(match方法),獲取加載在uri中的參數(shù)等操作。但我看來,這只是在使用上簡化了相關(guān)操作(不然就需要自己做人肉解析了.),但并沒有改變類型判定的模式。你依然需要用switch.case.對uri的類型進(jìn)行判斷,并進(jìn)行相關(guān)后續(xù)的操作。從模式來看
32、,這樣無疑是具有強(qiáng)烈的壞味道,類似的switch.case.代碼要出現(xiàn)N此,每次一個(gè) ContentProvider做uri類型的增減都會(huì)需要遍歷修改每一個(gè)switch.case.,當(dāng)然,如果你使用模式(策略模式.)進(jìn)行改造對手機(jī)程序來說無疑是崩潰似的(類型膨脹,效率降低.),所以,只能是忍一忍了(恩,還好不會(huì)擴(kuò)散到別的類中,維護(hù)性上不會(huì)有殺人性的麻煩.)。增刪改查ContentProvider 和所有數(shù)據(jù)源一樣,向外提供增刪改查操作接口,這些都是基于uri的指令。進(jìn)行insert操作的時(shí)候,你需要傳入一個(gè)uri和 ContentValues。uri的作用基本就限于指明增減條目的類型(從數(shù)據(jù)庫
33、層面來看就是table名),ContentValues是一個(gè) key/value表的封裝,提供方便的API進(jìn)行插入數(shù)據(jù)類型和數(shù)據(jù)值的設(shè)置和獲取。在數(shù)據(jù)庫層面上來看,這應(yīng)該是column name與value的對應(yīng)。但為了屏蔽ContentProvider用戶涉及到具體數(shù)據(jù)庫的細(xì)節(jié),在Android的示例中,用了一個(gè)小小的模式。它為每一個(gè)表建一個(gè)基于BaseColumn類的派生類(其實(shí)完全可以不派生自BaseColumn,特別當(dāng)你的表不基于默認(rèn)的自動(dòng)id做主鍵的時(shí)候),這個(gè)類通常包括一個(gè)描述該表的ContentURI對象和形如 public static final TITLE = "title"這樣的column到類數(shù)據(jù)的對應(yīng)。從改變上角度來看,你可以修改column的名字而不需要更改用戶上層代碼,增加了靈活性。 insert方法如果成功會(huì)返回一個(gè)uri,該uri會(huì)在原有的uri基礎(chǔ)上增加有一個(gè)row id。對于為什么使用row id而不是key id我想破了腦袋。到最后,我發(fā)現(xiàn)我傻了,因?yàn)镃ontentProvider不一定需要使用數(shù)據(jù)庫,使用數(shù)據(jù)庫對應(yīng)的表也可以沒有主鍵,只有row id,才能在任何底層介質(zhì)下做索引標(biāo)識(shí)。但,基于row id在刪除
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 西站框構(gòu)中橋施工方案 投標(biāo)方案(技術(shù)方案)
- 交通行業(yè)智能交通信號(hào)燈智能運(yùn)維與數(shù)據(jù)分析方案
- 市場拓展整車運(yùn)輸合同模板
- 三農(nóng)產(chǎn)品產(chǎn)銷對接方案參考手冊
- 《網(wǎng)頁設(shè)計(jì)與制作》課件-靜態(tài)網(wǎng)頁與動(dòng)態(tài)網(wǎng)頁
- 2025年小學(xué)教師資格考試《綜合素質(zhì)》教育案例全面分析及反思試題(含答案)
- 2025年消防執(zhí)業(yè)資格考試題庫:消防應(yīng)急救援裝備性能測試與試題
- 2025年安全生產(chǎn)隱患排查治理考試模擬題庫
- 2025年ACCA國際注冊會(huì)計(jì)師考試真題卷:審計(jì)實(shí)務(wù)與準(zhǔn)則歷年真題解析與備考指南寶典
- 2025年西班牙語DELE考試真題卷:模擬試題與解題技巧解析試題
- 2025年海南保亭縣事業(yè)單位招聘綜合歷年高頻重點(diǎn)模擬試卷提升(共500題附帶答案詳解)
- 污水處理設(shè)施運(yùn)維服務(wù)投標(biāo)方案(技術(shù)標(biāo))
- 2024年蘇州高博軟件技術(shù)職業(yè)學(xué)院高職單招職業(yè)適應(yīng)性測試歷年參考題庫含答案解析
- 紀(jì)念抗日戰(zhàn)爭暨世界反法西斯戰(zhàn)爭勝利70周年主題班會(huì) 課件
- AB變頻器使用說明書
- 新疆維吾爾自治區(qū)和田地區(qū)各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會(huì)明細(xì)及行政區(qū)劃代碼
- DB13-T2355-2016蒸壓加氣混凝土砌塊專用砂漿
- 【課件】時(shí)代與變革-為人生而藝術(shù) 課件高中美術(shù)人美版(2019)美術(shù)鑒賞
- DB44∕T 876-2011 物業(yè)服務(wù) 會(huì)務(wù)服務(wù)規(guī)范
- 橫河氧量變送器標(biāo)定及檢修
- ArcGIS應(yīng)用基礎(chǔ)培訓(xùn)(共98張)
評論
0/150
提交評論