最全面的Android-Intent機(jī)制講解_第1頁(yè)
最全面的Android-Intent機(jī)制講解_第2頁(yè)
最全面的Android-Intent機(jī)制講解_第3頁(yè)
最全面的Android-Intent機(jī)制講解_第4頁(yè)
最全面的Android-Intent機(jī)制講解_第5頁(yè)
已閱讀5頁(yè),還剩4頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

最全面的AndroidIntent機(jī)制講解2013-05-2714:06佚名jizhuomi字號(hào):T|TAndroid中與Intent相關(guān)的還有Action/Category及IntentFilter等,另外還有用于廣播的Intent,這些元素?fù)诫s在一起,導(dǎo)致初學(xué)者不太容易迅速掌握Intent的用法。在講解這些名詞之前,我們先來(lái)從下面的例子中感受一下Intent的一些基本用法,看看它能做些什么,之后再來(lái)思考這種機(jī)制背后的意義。AD:WOT2014課程推薦:實(shí)戰(zhàn)MSA:用開(kāi)源軟件搭建微服務(wù)系統(tǒng)對(duì)于大型軟件開(kāi)發(fā)經(jīng)驗(yàn)較少的程序員來(lái)說(shuō),這可能是一個(gè)不太容易理解的抽象概念,因?yàn)樗c我們平常使用的簡(jiǎn)單函數(shù)調(diào)用,或者通過(guò)庫(kù)調(diào)用接口的方式不太一樣。在Intent的使用中你看不到直接的函數(shù)調(diào)用,相對(duì)函數(shù)調(diào)用來(lái)說(shuō),Intent是更為抽象的概念,利用Intent所實(shí)現(xiàn)的軟件復(fù)用的粒度是Activity/Service,比函數(shù)復(fù)用更高一些,另外耦合也更為松散。Android中與Intent相關(guān)的還有Action/Category及IntentFilter等,另外還有用于廣播的Intent,這些元素?fù)诫s在一起,導(dǎo)致初學(xué)者不太容易迅速掌握Intent的用法。在講解這些名詞之前,我們先來(lái)從下面的例子中感受一下Intent的一些基本用法,看看它能做些什么,之后再來(lái)思考這種機(jī)制背后的意義。理解Intent的關(guān)鍵之一是理解清楚Intent的兩種基本用法:一種是顯式的Intent,即在構(gòu)造Intent對(duì)象時(shí)就指定接收者,這種方式與普通的函數(shù)調(diào)用類似,只是復(fù)用的粒度有所差別;另一種是隱式的Intent,即Intent的發(fā)送者在構(gòu)造Intent對(duì)象時(shí),并不知道也不關(guān)心接收者是誰(shuí),這種方式與函數(shù)調(diào)用差別比較大,有利于降低發(fā)送者和接收者之間的耦合。另外Intent除了發(fā)送外,還可用于廣播。下面的一小節(jié)我們來(lái)看看顯式Intent的用法。顯式的Intent(ExplicitIntent)同一個(gè)應(yīng)用程序中的Activity切換通常一個(gè)應(yīng)用程序中需要多個(gè)UI屏幕,也就需要多個(gè)Activity類,并且在這些Activity之間進(jìn)行切換,這種切換就是通過(guò)Intent機(jī)制來(lái)實(shí)現(xiàn)的。在同一個(gè)應(yīng)用程序中切換Activity時(shí),我們通常都知道要啟動(dòng)的Activity具體是哪一個(gè),因此常用顯式的Intent來(lái)實(shí)現(xiàn)。下面的例子用來(lái)實(shí)現(xiàn)一個(gè)非常簡(jiǎn)單的應(yīng)用程序SimpleIntentTest,它包括兩個(gè)UI屏幕也就是兩個(gè)Activity——SimpleIntentTest類和TestActivity類,SimpleIntentTest類有一個(gè)按鈕用來(lái)啟動(dòng)TestActivity。程序的代碼非常簡(jiǎn)單,SimpleIntentTest類的源代碼如下:packageent.simple;importandroid.app.Activity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.Button;publicclassSimpleIntentTestextendsActivityimplementsView.OnClickListener{/**Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);ButtonstartBtn=(Button)findViewById(R.id.start_activity);startBtn.setOnClickListener(this);}publicvoidonClick(Viewv){switch(v.getId()){caseR.id.start_activity:Intentintent=newIntent(this,TestActivity.class);startActivity(intent);break;default:break;}}}上面的代碼中,主要是為“Startactivity”按鈕添加了OnClickListener,使得按鈕被點(diǎn)擊時(shí)執(zhí)行onClick()方法,onClick()方法中則利用了Intent機(jī)制,來(lái)啟動(dòng)TestActivity,關(guān)鍵的代碼是下面這兩行:Intentintent=newIntent(this,TestActivity.class);startActivity(intent);這里定義Intent對(duì)象時(shí)所用到的是Intent的構(gòu)造函數(shù)之一:Intent(ContextpackageContext,Class<?>cls)兩個(gè)參數(shù)分別指定Context和Class,由于將Class設(shè)置為T(mén)estActivity.class,這樣便顯式的指定了TestActivity類作為該Intent的接收者,通過(guò)后面的startActivity()方法便可啟動(dòng)TestActivity。TestActivity的代碼更為簡(jiǎn)單(定義TestActivity類需要新建TestActivity.java文件,如果你是一個(gè)初學(xué)者,你需要學(xué)會(huì)如何在Eclipse或其他開(kāi)發(fā)環(huán)境下添加一個(gè)新的類,這里不作詳述,請(qǐng)參考其他文檔),如下所示:packageent.simple;importandroid.app.Activity;importandroid.os.Bundle;publicclassTestActivityextendsActivity{/**Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.test_activity);}}可見(jiàn)TestActivity僅僅是調(diào)用setContentView來(lái)顯示test_activity.xml中的內(nèi)容而已。對(duì)于test_activity.xml及本例中所用到其他xml文件這里不作多余說(shuō)明。如果我們僅僅是做上面的一些工作,還不能達(dá)到利用SimpleIntentTest啟動(dòng)TestActivity的目的。事實(shí)上,這樣做會(huì)出現(xiàn)下面的Exception,導(dǎo)致程序退出。以下是利用logcat工具記錄的log信息(省略了后半部分):

I/ActivityManager(569):Displayedactivitycom.tope.samples/.SimpleIntentTest:3018ms

I/ActivityManager(569):Startingactivity:Intent{comp={com.tope.samples/com.tope.samples.TestActivity}}

D/AndroidRuntime(932):ShuttingdownVM

W/dalvikvm(932):threadid=3:threadexitingwithuncaughtexception(group=0x4000fe70)

E/AndroidRuntime(932):Uncaughthandler:threadmainexitingduetouncaughtexception

E/AndroidRuntime(932):android.content.ActivityNotFoundException:Unabletofindexplicitactivityclass

{com.tope.samples/com.tope.samples.TestActivity};haveyoudeclaredthisactivityinyourAndroidManifest.xml?

E/AndroidRuntime(932):atandroid.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1480)

E/AndroidRuntime(932):atandroid.app.Instrumentation.execStartActivity(Instrumentation.java:1454)

E/AndroidRuntime(932):atandroid.app.Activity.startActivityForResult(Activity.java:2656)

E/AndroidRuntime(932):atandroid.app.Activity.startActivity(Activity.java:2700)

E/AndroidRuntime(932):atcom.tope.samples.SimpleIntentTest.onClick(SimpleIntentTest.java:24)

…從這些log中我們可以看到點(diǎn)擊按鈕后startActivity的調(diào)用過(guò)程,主要的原因是:“android.content.ActivityNotFoundException:Unabletofindexplicitactivityclass{com.tope.samples/com.tope.samples.TestActivity};haveyoudeclaredthisactivityinyourAndroidManifest.xml?”從這些log我們可以看到原因是找不到TestActivity這個(gè)Activity,并且log中還給出了提示:你是否在AndroidManifest.xml中聲明了這個(gè)Activity?解決問(wèn)題的方法也就是按照提示在AndroidManifest.xml中增加TestActivity的聲明,如下所示:<?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="/apk/res/android"package="com.tope.samples"android:versionCode="1"android:versionName="1.0"><applicationandroid:icon="@drawable/icon"android:label="@string/app_name"><activityandroid:name=".SimpleIntentTest"android:label="@string/app_name"><intent-filter><actionandroid:name="ent.action.MAIN"/><categoryandroid:name="ent.category.LAUNCHER"/></intent-filter></activity><activityandroid:name=".TestActivity"/></application><uses-sdkandroid:minSdkVersion="3"/></manifest>完成這個(gè)修改后再重新運(yùn)行該程序,就一切都正常了。別走開(kāi),下頁(yè)為您帶來(lái)Activity切換和隱式Intent從AndroidManifest.xml修改的過(guò)程我們可以體會(huì)到,Intent機(jī)制即使在程序內(nèi)部且顯式指定接收者,也還是需要在AndroidManifest.xml中聲明TestActivity。這個(gè)過(guò)程并不像一個(gè)簡(jiǎn)單的函數(shù)調(diào)用,顯式的Intent也同樣經(jīng)過(guò)了Android應(yīng)用程序框架所提供的支持,從滿足條件的Activity中進(jìn)行選擇,如果不在AndroidManifest.xml中進(jìn)行聲明,則Android應(yīng)用程序框架找不到所需要的Activity。請(qǐng)讀者通過(guò)我們的示例來(lái)逐步理解AndroidManifest.xml在這個(gè)過(guò)程中所扮演的角色,這樣有利于理解Intent的作用,及后面的IntentFilter。當(dāng)然,這個(gè)例子僅僅是開(kāi)始,且看下文分解。不同應(yīng)用程序之間的Activity切換上面的例子我們所做的是在同一應(yīng)用程序中進(jìn)行Activity的切換,那么在不同的應(yīng)用程序中,是否也能這么做呢,答案是肯定的,不過(guò)對(duì)應(yīng)的代碼要稍作修改。本例中我們需要兩個(gè)應(yīng)用程序,可利用上例中的SimpleIntentTest作為其中之一,另外還需要寫(xiě)一個(gè)新的程序,來(lái)調(diào)用SimpleIntentTest應(yīng)用程序中的TestActivity。我們新建程序CrossIntentTest(注意不是新建一個(gè)類,如果是Eclipse環(huán)境,選擇File->New->Project新建工程),其中只有一個(gè)Activity,其源代碼與SimpleIntentTest.java類似:packageent.cross;importandroid.app.Activity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.Button;publicclassCrossIntentTestextendsActivityimplementsView.OnClickListener{/**Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);ButtonstartBtn=(Button)findViewById(R.id.start_activity);startBtn.setOnClickListener(this);}publicvoidonClick(Viewv){switch(v.getId()){caseR.id.start_activity:Intentintent=newIntent();intent.setClassName("ent.simple",.ent.simple.TestActivity");startActivity(intent);break;default:break;}}}注意比較它與SimpleIntentTest的不同之處主要在于初始化Intent對(duì)象的過(guò)程:Intentintent=newIntent();intent.setClassName("ent.simple","ent.simple.TestActivity");startActivity(intent);這里采用了Intent最簡(jiǎn)單的不帶參數(shù)的構(gòu)造函數(shù),然后通過(guò)setClassName()函數(shù)來(lái)指定要啟動(dòng)哪個(gè)包中的哪個(gè)Activity,而不是像上例中的通過(guò)Intent(ContextpackageContext,Class<?>cls)這個(gè)構(gòu)造函數(shù)來(lái)初始化Intent對(duì)象,這是因?yàn)?,要啟?dòng)的TestActivity與CrossIntentTest不在同一個(gè)包中,要指定Class參數(shù)比較麻煩,所以通常啟動(dòng)不同程序的Activity時(shí)便采用上面的setClassName()的方式。除此之外,你也可以利用Android提供的類似的setComponent()方法,具體使用方法請(qǐng)參考AndroidSDK的文檔。另外我們還需要修改SimpleIntentTest程序中的AndroidManifest.xml文件,為T(mén)estActivity的聲明添加IntentFilter,即將原來(lái)的<activityandroid:name=".TestActivity"/>修改為:<activityandroid:name=".TestActivity"><intent-filter><actionandroid:name="ent.action.DEFAULT"/></intent-filter></activity>對(duì)于不同應(yīng)用之間的Activity的切換,這里需要在IntentFilter中設(shè)置至少一個(gè)Action,否則其他的應(yīng)用將沒(méi)有權(quán)限調(diào)用這個(gè)Activity。這里我們開(kāi)始接觸IntentFilter和Action這些概念了,讀者應(yīng)該可以感覺(jué)到,設(shè)置IntentFilter和Action主要的目的,是為了讓其他需要調(diào)用這個(gè)Activity的程序能夠順利的調(diào)用它。除了Action之外,IntentFilter還可以設(shè)置Category、Data等,用來(lái)更加精確的匹配Intent與Activity。隱式Intent(ImplicitIntent)如果Intent機(jī)制僅僅提供上面的顯式Intent用法的話,這種相對(duì)復(fù)雜的機(jī)制似乎意義并不是很大。確實(shí),Intent機(jī)制更重要的作用在于下面這種隱式的Intent,即Intent的發(fā)送者不指定接收者,很可能不知道也不關(guān)心接收者是誰(shuí),而由Android框架去尋找最匹配的接收者。最簡(jiǎn)單的隱式Intent我們先從最簡(jiǎn)單的例子開(kāi)始。下面的ImplicitIntentTest程序用來(lái)啟動(dòng)Android自帶的打電話功能的Dialer程序。ImplicitIntentTest程序只包含一個(gè)java源文件ImplicitIntentTest.java,代碼如下所示:packageent.implicit;importandroid.app.Activity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.Button;publicclassImplicitIntentTestextendsActivityimplementsView.OnClickListener{/**Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);ButtonstartBtn=(Button)findViewById(R.id.dial);startBtn.setOnClickListener(this);}publicvoidonClick(Viewv){switch(v.getId()){caseR.id.dial:Intentintent=newIntent(Intent.ACTION_DIAL);startActivity(intent);break;default:break;}}}該程序在Intent的使用上,與上節(jié)中的使用方式有很大的不同,即根本不指定接收者,初始化Intent對(duì)象時(shí),只是傳入?yún)?shù),設(shè)定Action為Intent.ACTION_DIAL:Intentintent=newIntent(Intent.ACTION_DIAL);startActivity(intent);這里使用的構(gòu)造函數(shù)的原型如下:Intent(Stringaction);這里讀者可暫時(shí)將action理解為描述這個(gè)Intent的一種方式,這種使用方式看上去比較奇怪,Intent的發(fā)送者只是指定了Action為Intent.ACTION_DIAL,那么怎么找到接收者呢?來(lái)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論