posts - 101,  comments - 29,  trackbacks - 0

                  在Android系統(tǒng)中,Content Provider作為應(yīng)用程序四大組件之一,它起到在應(yīng)用程序之間共享數(shù)據(jù)的作用,同時(shí),它還是標(biāo)準(zhǔn)的數(shù)據(jù)訪問(wèn)接口。前面的一系列文章已經(jīng)分析過(guò)Android應(yīng)用程序的其它三大組件(Activity、Service和Broadcast Receiver)了,本文將簡(jiǎn)要介紹Content Provider組件在Android應(yīng)用程序設(shè)計(jì)中的地位,為進(jìn)一步學(xué)習(xí)打好基礎(chǔ)。

                  我們知道,在Android系統(tǒng)上,每一個(gè)應(yīng)用程序都有一個(gè)獨(dú)立的用戶(hù)ID。為什么要給每一個(gè)應(yīng)用程序分配一個(gè)獨(dú)立的用戶(hù)ID呢?這是為了保護(hù)各個(gè)應(yīng)用程序的數(shù)據(jù)不被其它應(yīng)用程序惡意破壞而設(shè)計(jì)的。Android系統(tǒng)是基于Linux內(nèi)核來(lái)開(kāi)發(fā)的,而在Linux系統(tǒng)中,每一個(gè)文件除了文件本身的數(shù)據(jù)之外,還具有一定的屬性,其中最重要的就是文件權(quán)限了。所謂的文件權(quán)限,就是指對(duì)文件的讀、寫(xiě)和執(zhí)行權(quán)限。此外,Linux還是一個(gè)多用戶(hù)的操作系統(tǒng),因此,Linux將系統(tǒng)中的每一個(gè)文件都與一個(gè)用戶(hù)以及用戶(hù)組關(guān)聯(lián)起來(lái),基于不同的用戶(hù)而賦予不同的文件權(quán)限。只有當(dāng)一個(gè)用戶(hù)對(duì)某個(gè)文件擁有相應(yīng)的權(quán)限時(shí),才能執(zhí)行相應(yīng)的操作,例如,只有當(dāng)一個(gè)用戶(hù)對(duì)某個(gè)文件擁有讀權(quán)限時(shí),這個(gè)用戶(hù)才可以調(diào)用read系統(tǒng)調(diào)用來(lái)讀取這個(gè)文件的內(nèi)容。Android系統(tǒng)繼承了Linux系統(tǒng)管理文件的方法,為每一個(gè)應(yīng)用程序分配一個(gè)獨(dú)立的用戶(hù)ID和用戶(hù)組ID,而由這個(gè)應(yīng)用程序創(chuàng)建出來(lái)的數(shù)據(jù)文件就賦予相應(yīng)的用戶(hù)以及用戶(hù)組讀寫(xiě)的權(quán)限,其余用戶(hù)則無(wú)權(quán)對(duì)該文件進(jìn)行讀寫(xiě)。

                  如果我們通過(guò)adb shell命令連上模擬器,切換到/data/data目錄下,就可以看到很多以應(yīng)用程序包(package)命名的文件夾,這些文件夾里面存放的就是各個(gè)應(yīng)用程序的數(shù)據(jù)文件,例如,如果我們進(jìn)入到Android系統(tǒng)日歷應(yīng)用程序數(shù)據(jù)目錄com.android.providers.calendar下的databases文件中,會(huì)看到一個(gè)用來(lái)保存日歷數(shù)據(jù)的數(shù)據(jù)庫(kù)文件calendar.db,它的權(quán)限設(shè)置如下所示:

          root@android:/data/data/com.android.providers.calendar/databases # ls -l
          -rw-rw---- app_17   app_17      33792 2011-11-07 15:50 calendar.db

           

                  在前面的十字符-rw-rw----中,最前面的符號(hào)-表示這是一個(gè)普通文件,接下來(lái)的三個(gè)字符rw-表示這個(gè)文件的所有者對(duì)這個(gè)文件可讀可寫(xiě)不可執(zhí)行,再接下來(lái)的三個(gè)字符rw-表示這個(gè)文件的所有者所在的用戶(hù)組的用戶(hù)對(duì)這個(gè)文件可讀可寫(xiě)不可執(zhí)行,而最后的三個(gè)字符---表示其它的用戶(hù)對(duì)這個(gè)文件不可讀寫(xiě)也不可執(zhí)行,因?yàn)檫@是一個(gè)數(shù)據(jù)文件,所認(rèn)所有用戶(hù)都不可以執(zhí)行它是正確的。在接下來(lái)的兩個(gè)app_17字符串表示這個(gè)文件的所有者和這個(gè)所有者所在的用戶(hù)組的名稱(chēng)均為app_17,這是應(yīng)用程序在安裝的時(shí)候系統(tǒng)分配的,在不同的系統(tǒng)上,這個(gè)字符串可能是不一樣,不過(guò)它所表示的意義是一樣的。這意味著只有用戶(hù)ID為app_17或者用戶(hù)組ID為app_17的那些進(jìn)程才可以對(duì)這個(gè)calendar.db文件進(jìn)行讀寫(xiě)操作。我們通過(guò)執(zhí)行終端上執(zhí)行ps命令來(lái)查看一下哪個(gè)進(jìn)程的用戶(hù)ID為app_17

          root@android:/ # ps
          USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
          root      1     0     272    184   c009f230 0000875c S /init
          ...      ...   ...    ...    ...      ...    ...         ...
          app_17   295   35    107468 21492 ffffffff afd0c38c  S com.android.providers.calendar
          ..       ...   ...    ...    ...      ...    ...         ...
          root     556   527   892    332   00000000 afd0b24c  R ps
                  這里我們看到,正是這個(gè)日歷應(yīng)用程序com.android.providers.calendar進(jìn)程的用戶(hù)ID為app_17這樣,就驗(yàn)證了我們前面的分析了:只有這個(gè)日歷應(yīng)用程序com.android.providers.calendar才可以對(duì)這個(gè)calendar.db文件進(jìn)行讀寫(xiě)操作。這個(gè)日歷應(yīng)用程序com.android.providers.calendar其實(shí)是由一個(gè)Content Provider組件來(lái)實(shí)現(xiàn)的,在下一篇文章中,我們將實(shí)現(xiàn)一個(gè)自己的Content Provider,然后再對(duì)Content Provider的實(shí)現(xiàn)原理進(jìn)行詳細(xì)分析。

           

                  Android系統(tǒng)對(duì)應(yīng)用程序的數(shù)據(jù)文件作如此嚴(yán)格的保護(hù)會(huì)不會(huì)有點(diǎn)過(guò)頭了呢?如果一個(gè)應(yīng)用程序想要讀寫(xiě)另外一個(gè)應(yīng)用程序的數(shù)據(jù)文件時(shí),應(yīng)該怎么辦呢?舉一個(gè)典型的應(yīng)用場(chǎng)景,我們?cè)陂_(kāi)發(fā)自己的應(yīng)用程序時(shí),有時(shí)候會(huì)希望讀取通訊錄里面某個(gè)聯(lián)系人的手機(jī)號(hào)碼或者電子郵件,以便可以對(duì)這個(gè)聯(lián)系人打電話(huà)或者發(fā)送電子郵件,這時(shí)候就需要讀取通訊錄里面的聯(lián)系人數(shù)據(jù)文件了。

                  現(xiàn)在在互聯(lián)網(wǎng)里面,都流行平臺(tái)的概念,各大公司都打著開(kāi)放平臺(tái)的口號(hào),來(lái)吸引第三方來(lái)為自己的平臺(tái)做應(yīng)用,例如,國(guó)外最流行的Fackbook開(kāi)放平臺(tái)和Google+開(kāi)放平臺(tái)等,國(guó)內(nèi)的有騰訊的Q+開(kāi)放平臺(tái),還有新浪微博開(kāi)放平臺(tái)、360的開(kāi)放平臺(tái)等。這些開(kāi)放平臺(tái)的核心就是要開(kāi)放用戶(hù)數(shù)據(jù)給第三方來(lái)使使用,就像前面我們說(shuō)的Android系統(tǒng)的通訊錄,它需要把自己聯(lián)系人數(shù)據(jù)開(kāi)放出來(lái)給其它應(yīng)用程序使用。但是,這些數(shù)據(jù)都是各個(gè)平臺(tái)自己的核心數(shù)據(jù)和核心競(jìng)爭(zhēng)力,它們需要有保護(hù)地進(jìn)行開(kāi)放。Android系統(tǒng)中的Content Provider應(yīng)用程序組件正是結(jié)合上面分析的這種文件權(quán)限機(jī)制來(lái)秉承這種有保護(hù)地開(kāi)放自己的數(shù)據(jù)給其它應(yīng)用程序使用的理念。

                  從另外一個(gè)觀點(diǎn)來(lái)看,即使我們不是在做平臺(tái),而只是在做一個(gè)應(yīng)用程序軟件,是不是就不需要這么使用到Content Provider機(jī)制了呢?非也,現(xiàn)在的應(yīng)用程序軟件,越著公司業(yè)務(wù)的成長(zhǎng),越來(lái)越龐大,越來(lái)越復(fù)雜。軟件工程告訴我們,我們?cè)谠O(shè)計(jì)這種大型的復(fù)雜的軟件的時(shí)候,需要分模塊和分層次來(lái)實(shí)現(xiàn)各個(gè)子功能組件,使得各個(gè)模塊功能以松耦合的方式組織在一起完成整個(gè)應(yīng)用程序功能。這樣做的好處當(dāng)然就是便于我們維護(hù)和擴(kuò)展應(yīng)用程序的代碼和功能了,以及適應(yīng)復(fù)雜的業(yè)務(wù)環(huán)境。在一個(gè)大型的應(yīng)用程序軟件架構(gòu)中,從垂直的方向來(lái)看,一般都會(huì)劃分為數(shù)據(jù)層、數(shù)據(jù)訪問(wèn)接口層以及上面的業(yè)務(wù)層。數(shù)據(jù)層用來(lái)保存數(shù)據(jù),這些數(shù)據(jù)可以用文件的方式來(lái)組織,也可以用數(shù)據(jù)庫(kù)的方式來(lái)組織,甚至可以保存在網(wǎng)絡(luò)中;數(shù)據(jù)訪問(wèn)層負(fù)責(zé)向上面的業(yè)務(wù)層提供數(shù)據(jù),而向下管理好數(shù)據(jù)層的數(shù)據(jù);最后業(yè)務(wù)層通過(guò)數(shù)據(jù)訪問(wèn)層來(lái)獲取一些業(yè)務(wù)相關(guān)的數(shù)據(jù)來(lái)實(shí)現(xiàn)自己的業(yè)務(wù)邏輯。

                  基于這種開(kāi)放平臺(tái)建設(shè)或者復(fù)雜軟件架構(gòu)的理念,我們得出一個(gè)Android應(yīng)用程序設(shè)計(jì)的一般方法,如下圖所示:


                  在這個(gè)架構(gòu)中, 數(shù)據(jù)層采用數(shù)據(jù)庫(kù)、文件或者網(wǎng)絡(luò)來(lái)保存數(shù)據(jù),數(shù)據(jù)訪問(wèn)層使用Content Provider來(lái)實(shí)現(xiàn),而業(yè)務(wù)層就通過(guò)一些APP來(lái)實(shí)現(xiàn)。為了降低各個(gè)功能模塊間耦合性,我們可以把業(yè)務(wù)層的各個(gè)APP和數(shù)據(jù)訪問(wèn)層中的Content Provider,放在不同的應(yīng)用程序進(jìn)程中來(lái)實(shí)現(xiàn),而數(shù)據(jù)庫(kù)中的數(shù)據(jù)統(tǒng)一由Content Provider來(lái)管理,即Content Provider擁有對(duì)這些文件直接進(jìn)行讀寫(xiě)的權(quán)限,同時(shí),它又根據(jù)需要來(lái)有保護(hù)地把這些數(shù)據(jù)開(kāi)放出來(lái)給上層的APP來(lái)使用。

                  那么,Content Provider又是如何把數(shù)據(jù)開(kāi)放給上面的APP使用呢?一方面是這些APP沒(méi)有權(quán)限讀取這些數(shù)據(jù)文件,另一外面是Content Provider和這些APP是在不同的進(jìn)程空間里面。回憶一下,我們?cè)谇懊?a >Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃這一系文章中學(xué)習(xí)的Android系統(tǒng)中Binder進(jìn)程間通信機(jī)制,不同的應(yīng)用程序之間可以通過(guò)Binder進(jìn)程間調(diào)用來(lái)傳輸數(shù)據(jù)。因此,前面關(guān)于一個(gè)應(yīng)用程序應(yīng)該如何來(lái)讀寫(xiě)另外一個(gè)應(yīng)用程序的數(shù)據(jù)的問(wèn)題的答案就是使用Binder進(jìn)程間通信機(jī)制,雖然一個(gè)應(yīng)用程序不能直接讀取另一個(gè)應(yīng)用程序的數(shù)據(jù),但是它卻可以通過(guò)進(jìn)程間通信方式來(lái)請(qǐng)求另一個(gè)這個(gè)應(yīng)用程序給它傳輸數(shù)據(jù)。這樣我們就解決了文件權(quán)限限制所帶來(lái)的問(wèn)題了。

                  然而,事情還不是那么簡(jiǎn)單,一般Content  Provider管理的都是大量的數(shù)據(jù),如果在進(jìn)程間傳輸大量的數(shù)據(jù),效率是不是會(huì)很低下呢?這時(shí)候,前面我們?cè)?a >Android系統(tǒng)匿名共享內(nèi)存Ashmem(Anonymous Shared Memory)簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃這一系列文章中學(xué)習(xí)的匿名共享內(nèi)存(Anonymous Shared Memory)就派上用場(chǎng)了。把需要在進(jìn)程間傳輸?shù)臄?shù)據(jù)都寫(xiě)到共享內(nèi)存中去,然后只能通過(guò)Binder進(jìn)程間通信機(jī)制來(lái)傳輸一個(gè)共享內(nèi)存的打開(kāi)文件描述符給對(duì)方就好了,是不是很簡(jiǎn)單呢。在Android系統(tǒng)中,Binder進(jìn)程間通信機(jī)制和匿名共享內(nèi)存機(jī)制結(jié)合在一起使用,真是太完美了。

                  Content Provider如何在應(yīng)用程序之間共享數(shù)據(jù)以及它在應(yīng)用程序設(shè)計(jì)中的地位就簡(jiǎn)要介紹到這里了,在接下來(lái)的四篇文章中,我們將以一個(gè) Content Provider的應(yīng)用實(shí)例來(lái)詳細(xì)分析它的啟動(dòng)過(guò)程、數(shù)據(jù)共享原理以及數(shù)據(jù)監(jiān)控機(jī)制:

                  1. Android應(yīng)用程序組件Content Provider的應(yīng)用實(shí)例

                  2. Android應(yīng)用程序組件Content Provider的啟動(dòng)過(guò)程源代碼分析

                  3. Android應(yīng)用程序組件Content Provider在不同應(yīng)用程序之間共享數(shù)據(jù)的原理分析

                  4. Android應(yīng)用程序組件Content Provider的數(shù)據(jù)監(jiān)控機(jī)制分析

                  敬請(qǐng)關(guān)注!

          作者:Luoshengyang 發(fā)表于2011-11-14 1:03:13 原文鏈接
          閱讀:4331 評(píng)論:27 查看評(píng)論
          posted on 2012-04-17 21:32 mixer-a 閱讀(262) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 洛南县| 保康县| 惠水县| 沧源| 东宁县| 新泰市| 融水| 团风县| 兰州市| 图片| 嘉定区| 古丈县| 竹山县| 平昌县| 城固县| 泸水县| 天等县| 玉林市| 岳阳县| 岳西县| 海宁市| 贡嘎县| 伊通| 定结县| 阳谷县| 武乡县| 达尔| 兴安县| 张家口市| 鹿泉市| 来凤县| 台中市| 淮南市| 开远市| 扎赉特旗| 茂名市| 正宁县| 科技| 佳木斯市| 黑水县| 洛川县|