Android系統(tǒng)中進(jìn)程間通訊的4種方式

由于android系統(tǒng)中應(yīng)用程序之間不能共享內(nèi)存。

因此佳晶,在不同應(yīng)用程序之間交互數(shù)據(jù)(跨進(jìn)程通訊)就稍微麻煩一些愚屁。系統(tǒng)提供了4種跨進(jìn)程通訊的方式。對(duì)應(yīng)于應(yīng)用程序四大組件:

Activity

Content Provider

Broadcast

Service

其中Activity可以跨進(jìn)程調(diào)用其他應(yīng)用程序的Activity伟恶;

Content Provider可以跨進(jìn)程訪問其他應(yīng)用程序中的數(shù)據(jù)(以Cursor對(duì)象形式返回),也可以對(duì)其進(jìn)行增毅该、刪博秫、改操作潦牛;Broadcast可以向android系統(tǒng)中所有應(yīng)用程序發(fā)送廣播,而需要跨進(jìn)程通訊的應(yīng)用程序可以監(jiān)聽這些廣播挡育;

Service和Content Provider類似巴碗,也可以訪問其他應(yīng)用程序中的數(shù)據(jù),但不同的是即寒,Content Provider返回的是Cursor對(duì)象橡淆,而Service返回的是Java對(duì)象,這種可以跨進(jìn)程通訊的服務(wù)叫AIDL服務(wù)蒿叠。

方式一:訪問其他應(yīng)用程序的Activity

Activity既可以在進(jìn)程內(nèi)(同一個(gè)應(yīng)用程序)訪問明垢,也可以跨進(jìn)程訪問。

在同一個(gè)應(yīng)用程序中訪問Activity市咽,需要指定Context對(duì)象和Activity的Class對(duì)象痊银,代碼如下:

Intent intent = new ?Intent(this , Test.class );

startActivity(intent);

Activity的跨進(jìn)程訪問與進(jìn)程內(nèi)訪問略有不同。雖然它們都需要Intent對(duì)象施绎,但跨進(jìn)程訪問并不需要指定Context對(duì)象和Activity的Class對(duì)象溯革,而需要指定的是要訪問的Activity所對(duì)應(yīng)的Action(一個(gè)字符串)。有些Activity還需要指定一個(gè)Uri(通過Intent構(gòu)造方法的第2個(gè)參數(shù)指定)谷醉。

在android系統(tǒng)中有很多應(yīng)用程序提供了可以跨進(jìn)程訪問的Activity致稀,例如,下面的代碼可以直接調(diào)用撥打電話的Activity俱尼。

Intent callIntent = new ?Intent(Intent.ACTION_CALL, Uri.parse("tel://13888888888" );

startActivity(callIntent);

執(zhí)行上面的代碼后抖单,系統(tǒng)會(huì)自動(dòng)撥號(hào).

在調(diào)用撥號(hào)程序的代碼中使用了一個(gè)Intent.ACTION_CALL常量,該常量的定義如下:

public ?static ?final ?String ACTION_CALL = "android.intent.action.CALL" ;

這個(gè)常量是一個(gè)字符串常量遇八,也是我們?cè)谶@節(jié)要介紹的跨進(jìn)程調(diào)用Activity的關(guān)鍵矛绘。如果在應(yīng)用程序中要共享某個(gè)Activity,需要為這個(gè)Activity指定一個(gè)字符串ID刃永,也就是Action货矮。也可以將這個(gè)Action看做這個(gè)Activity的key。在其他的應(yīng)用程序中只要通過這個(gè)Action就可以找到與Action對(duì)應(yīng)的Activity斯够,并通過startActivity方法來啟動(dòng)這個(gè)Activity囚玫。

下面先來看一下如何將應(yīng)用程序的Activity共享出來,讀者可按如下幾步來共享Activity:

1. ?在AndroidManifest.xml文件中指定Action读规。指定Action要使用標(biāo)簽抓督,并在該標(biāo)簽的android:name屬性中指定Action

2. ?在AndroidManifest.xml文件中指定訪問協(xié)議。在指定Uri(Intent類的第2個(gè)參數(shù))時(shí)需要訪問協(xié)議束亏。訪問協(xié)議需要使 用標(biāo)簽的android:scheme屬性來指定铃在。如果該屬性的值是“mdm”,那么Uri就應(yīng)該是“mdm://Uri的主體 部分”枪汪,也就是說涌穆,訪問協(xié)議是Uri的開頭部分。

3. ?通過getIntent().getData().getHost()方法獲得協(xié)議后的Uri的主體部分雀久。這個(gè)Host只是個(gè)稱謂宿稀,并不一定是主機(jī)名。讀者可以將其看成是任意的字符串赖捌。

4. ?從Bundle對(duì)象中獲得其他應(yīng)用程序傳遞過來的數(shù)據(jù)祝沸。

5. ?這一步當(dāng)然是獲得數(shù)據(jù)后做進(jìn)一步的處理了。至于如何處理這些數(shù)據(jù)越庇,就得根據(jù)具體的需求決定了罩锐。

下面來根據(jù)這些步驟共享一個(gè)Activity。首先建立一個(gè)android工程(ActionActivity)卤唉,工程的主Activity是Main涩惑。在 本例中我們會(huì)共享這個(gè)Main類。首先打開AndroidManifest.xml文件桑驱,添加一個(gè)標(biāo)簽竭恬,并重新定義了Main的相應(yīng)屬性。AndroidManifest.xml文件的內(nèi)容如下:

注冊(cè)Activity

在配置AndroidManifest.xml時(shí)要注意熬的,不能在同一個(gè)<activity>中配置多個(gè)動(dòng)作痊硕,否則會(huì)覆蓋MAIN動(dòng)作以使該程序無法正常啟動(dòng)(雖然其他應(yīng)用程序調(diào)用Main是正常的).

標(biāo)簽指定了Url的協(xié)議,則在調(diào)用Main時(shí)需要使用如下的URL:

mdm://任意字符串

一般標(biāo)簽的android:name屬性值可以設(shè)成android.intent.category.DEFAULT,這個(gè)必須要設(shè)置,不然無法訪問到押框。

下面來看看如何在Main類的onCreate方法中獲得其他應(yīng)用程序傳遞過來的數(shù)據(jù)岔绸。

共享MainActivity接收數(shù)據(jù)代碼

從上面的程序可以看出,首先通過getIntent().getData()來判斷其他的應(yīng)用程序是否傳遞了Uri(getData方法返回了一個(gè)Uri 對(duì)象)橡伞。

下面來看一下其他的應(yīng)用程序是如何調(diào)用MainActivity的盒揉。新建一個(gè)android工程(InvokeActivity),并添加一個(gè)按鈕骑歹,按鈕的單擊事件方法代碼如下:

調(diào)用共享MainActivity代碼

從本節(jié)的介紹可以看出预烙,跨進(jìn)程訪問Activity(訪問其他應(yīng)用程序中的Activity)主要是通過一個(gè)Action來完成的,如果要傳遞數(shù)據(jù)道媚,還需 要指定一個(gè)Uri扁掸。當(dāng)然,傳遞數(shù)據(jù)也可以通過Intent來完成最域。傳遞數(shù)據(jù)的過程可以是雙向的谴分。如果要想從調(diào)用的Activity中返回?cái)?shù)據(jù),就需要使用startActivityForResult方法來啟動(dòng)Activity了镀脂。

方式二:Content Provider

Android應(yīng)用程序可以使用文件或SqlLite數(shù)據(jù)庫來存儲(chǔ)數(shù)據(jù)牺蹄。Content Provider提供了一種在多個(gè)應(yīng)用程序之間數(shù)據(jù)共享的方式(跨進(jìn)程共享數(shù)據(jù))。應(yīng)用程序可以利用Content Provider完成下面的工作

1. 查詢數(shù)據(jù)

2. 修改數(shù)據(jù)

3. 添加數(shù)據(jù)

4. 刪除數(shù)據(jù)

雖然Content Provider也可以在同一個(gè)應(yīng)用程序中被訪問薄翅,但這么做并沒有什么意義沙兰。Content Provider存在的目的向其他應(yīng)用程序共享數(shù)據(jù)和允許其他應(yīng)用程序?qū)?shù)據(jù)進(jìn)行增氓奈、刪、改操作鼎天。

Android系統(tǒng)本身提供了很多Content Provider舀奶,例如,音頻斋射、視頻育勺、聯(lián)系人信息等等。我們可以通過這些Content Provider獲得相關(guān)信息的列表罗岖。這些列表數(shù)據(jù)將以Cursor對(duì)象返回涧至。因此,從Content Provider返回的數(shù)據(jù)是二維表的形式桑包。

對(duì)于訪問Content Provider的程序南蓬,需要使用ContentResolver對(duì)象。該對(duì)象需要使用getContentResolver方法獲得哑了,代碼如下:

ContentResolver cr = getContentResolver();

與Activity一樣蓖康,Content Provider也需要與一個(gè)URI對(duì)應(yīng)。每一個(gè)Content Provider可以控制多個(gè)數(shù)據(jù)集垒手,在這種情況下蒜焊,每一個(gè)數(shù)據(jù)集會(huì)對(duì)應(yīng)一個(gè)單獨(dú)的URI。所有的URI必須以“content://”開頭科贬。

為了程序更容易維護(hù)泳梆,也為了簡化程序代碼,一般將URI定義成一個(gè)常量榜掌。例如优妙,下面的常量表示系統(tǒng)的聯(lián)系人電話號(hào)碼。

android.provider.Contacts.Phones.CONTENT_URI

下面來看一下編寫Content Provider的具體步驟憎账。

1. ?編寫一個(gè)繼承于android.content.ContentProvider的子類套硼。該類是ContentProvider的核心類。在該類中會(huì)實(shí)現(xiàn)query胞皱、insert邪意、update及delete方法。實(shí)際上調(diào)用ContentResolver類的這4個(gè)方法就是調(diào)用ContentProvider類中與之要對(duì)應(yīng)的方法反砌。在本文中只介紹query雾鬼。至于insert、update宴树、delete和query的用法類 似策菜。也是通過Uri傳遞參數(shù),然后在這些方法中接收這些參數(shù),并做進(jìn)一步地處理又憨。

2. ?在AndroidManifest.xml文件中配置ContentProvider翠霍。要想唯一確定一個(gè)ContentProvider,需要指定這個(gè)ContentProvider的URI蠢莺,除此之外壶运,還需要指定URI所對(duì)應(yīng)的ContentProvider類。這有些象Servlet的定義浪秘,除了要 指定Servlet對(duì)應(yīng)的Web地址,還要指定這個(gè)地址所對(duì)應(yīng)的Servlet類埠况。

現(xiàn)在來看一下Uri的具體格式耸携,先看一下如圖5所示的URI。

圖5

下面對(duì)圖5所示的URI的4個(gè)部分做一下解釋辕翰。

A:Content Provider URI的固定前綴夺衍,也就是說,所有的URI必須以content://開頭喜命。

B:URI中最重要的部分沟沙。該部分是Content Provider的唯一標(biāo)識(shí)。對(duì)于第三方應(yīng)用程序來說壁榕,該部分最后使用完整的類名(包名+類名)矛紫,以確保URI的唯一性。該部分需要在AndroidManifest.xml文件中標(biāo)簽中定義牌里,代碼如下:

注冊(cè)provider authorities

C:這部分是URI的路徑(path)颊咬。表示URI中各種被請(qǐng)求的數(shù)據(jù)。這部分是可選的牡辽, 如果Content Provider僅僅提供一種請(qǐng)求的數(shù)據(jù)喳篇,那么這部分可以省略。如果Content Provider要提供多種請(qǐng)求數(shù)據(jù)态辛。就需要添加多個(gè)路徑麸澜,甚至是子路徑。例如奏黑,“l(fā)and/bus”炊邦、“l(fā)and/train”、“sea/ship” 就指定了3種可能提供的數(shù)據(jù)熟史。

D:這部分也是可選的铣耘。如果要傳遞一個(gè)值給Content Provider,可以通過這部分傳遞以故。當(dāng)然蜗细,如果不需要傳值,這部分也可以省略,省略后的URI如下所示:

content://com.example.transportationprovider/trains

定義一個(gè)類繼承ContentProvider

查詢方法的實(shí)現(xiàn)

調(diào)用查詢接口代碼:

Uri CONTENT_URI = Uri.parse("content://com.polysaas.mcm/media_doc")

Cursor localCursor =contentResolver.query(CONTENT_URI, null, null, null, null);

待續(xù).......

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末炉媒,一起剝皮案震驚了整個(gè)濱河市踪区,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吊骤,老刑警劉巖缎岗,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異白粉,居然都是意外死亡传泊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門鸭巴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眷细,“玉大人,你說我怎么就攤上這事鹃祖∠担” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵恬口,是天一觀的道長校读。 經(jīng)常有香客問我,道長祖能,這世上最難降的妖魔是什么歉秫? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮养铸,結(jié)果婚禮上端考,老公的妹妹穿的比我還像新娘。我一直安慰自己揭厚,他們只是感情好却特,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著筛圆,像睡著了一般裂明。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上太援,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天闽晦,我揣著相機(jī)與錄音,去河邊找鬼提岔。 笑死仙蛉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碱蒙。 我是一名探鬼主播荠瘪,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼夯巷,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了哀墓?” 一聲冷哼從身側(cè)響起趁餐,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎篮绰,沒想到半個(gè)月后后雷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吠各,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年臀突,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贾漏。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡候学,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出磕瓷,到底是詐尸還是另有隱情,我是刑警寧澤念逞,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布困食,位于F島的核電站,受9級(jí)特大地震影響翎承,放射性物質(zhì)發(fā)生泄漏硕盹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一叨咖、第九天 我趴在偏房一處隱蔽的房頂上張望瘩例。 院中可真熱鬧,春花似錦春锋、人聲如沸笤闯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽聘惦。三九已至,卻和暖如春儒恋,著一層夾襖步出監(jiān)牢的瞬間善绎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工诫尽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留禀酱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓牧嫉,卻偏偏與公主長得像剂跟,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 由于android系統(tǒng)中應(yīng)用程序之間不能共享內(nèi)存浩聋。因此观蜗,在不同應(yīng)用程序之間交互數(shù)據(jù)(跨進(jìn)程通訊)就稍微麻煩一些。在...
    Ten_Minutes閱讀 8,466評(píng)論 1 7
  • 1.什么是Activity?問的不太多,說點(diǎn)有深度的 四大組件之一,一般的,一個(gè)用戶交互界面對(duì)應(yīng)一個(gè)activit...
    JoonyLee閱讀 5,737評(píng)論 2 51
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評(píng)論 25 707
  • 因?yàn)樘焐芪孟x青睞的體質(zhì)坊夫,向來旅游能走多北砖第,就走多北。所以非洲环凿,本是絕對(duì)不會(huì)放在旅行計(jì)劃內(nèi)的梧兼。 然而無所圖時(shí)常有際...
    古城扇閱讀 284評(píng)論 0 2
  • 我家有個(gè)小小人 可愛淘氣又好奇 即滿一周又一月 蹣跚學(xué)步如醉酒 跌跌撞撞往前沖 左拿右扯闖“江湖” 可他哪知“江湖...
    易小布閱讀 133評(píng)論 0 0