国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

最全面的Android Intent機制講解

移動開發 Android
Android中與Intent相關的還有Action/Category及Intent Filter等,另外還有用于廣播的Intent,這些元素摻雜在一起,導致初學者不太容易迅速掌握Intent的用法。在講解這些名詞之前,我們先來從下面的例子中感受一下Intent的一些基本用法,看看它能做些什么,之后再來思考這種機制背后的意義。

對于大型軟件開發經驗較少的程序員來說,這可能是一個不太容易理解的抽象概念,因為它與我們平常使用的簡單函數調用,或者通過庫調用接口的方式不太 一樣。在 Intent 的使用中你看不到直接的函數調用,相對函數調用來說,Intent 是更為抽象的概念,利用 Intent 所實現的軟件復用的粒度是Activity/Service ,比函數復用更高一些,另外耦合也更為松散。

Android 中與Intent 相關的還有 Action/Category 及 Intent Filter 等,另外還有用于廣播的 Intent ,這些元素摻雜在一起,導致初學者不太容易迅速掌握 Intent 的用法。在講解這些名詞之前,我們先來從下面的例子中感受一下 Intent 的一些基本用法,看看它能做些什么,之后再來思考這種機制背后的意義。

理解 Intent 的關鍵之一是理解清楚Intent 的兩種基本用法:一種是顯式的 Intent ,即在構造 Intent 對象時就指定接收者,這種方式與普通的函數調用類似, 只是復用的粒度有所差別;另一種是隱式的 Intent ,即Intent 的發送者在構造 Intent 對象時,并不知道也不關心接收者是誰,這種方式與函數調用差別比較大,有利于降低發送者和接收 者之間的耦合。另外 Intent 除了發送外,還可用于廣播。

下面的一小節我們來看看顯式 Intent 的用法。

顯式的Intent(Explicit Intent)

同一個應用程序中的Activity切換

通常一個應用程序中需要多個UI 屏幕,也就需要多個Activity 類,并且在這些 Activity 之間進行切換,這種切換就是通過 Intent 機制來實現的。

在同一個應用程序中切換 Activity時,我們通常都知道要啟動的 Activity 具體是哪一個,因此常用顯式的 Intent 來實現。下面的例子用來實現一個非常簡單的應用程序 SimpleIntentTest ,它包括兩個UI 屏幕也就是兩個 Activity——SimpleIntentTest類和 TestActivity 類, SimpleIntentTest類有一個按鈕用來啟動 TestActivity。

程序的代碼非常簡單, SimpleIntentTest類的源代碼如下:

  1. package  com.tope.samples.intent.simple;    
  2. import  android.app.Activity;    
  3. import  android.content.Intent;    
  4. import  android.os.Bundle;    
  5. import  android.view.View;    
  6. import  android.widget.Button;    
  7. public   class  SimpleIntentTest  extends  Activity  implements  View.OnClickListener{    
  8.      /**   Called   when   the   activity   is   first   created.   */   
  9.      @Override   
  10.      public   void  onCreate(Bundle savedInstanceState) {    
  11.          super .onCreate(savedInstanceState);    
  12.         setContentView(R.layout. main );    
  13.         Button startBtn = (Button)findViewById(R.id. start_activity );    
  14.         startBtn.setOnClickListener( this );    
  15.     }    
  16.      public   void  onClick(View v) {    
  17.          switch  (v.getId()) {    
  18.          case  R.id. start_activity :    
  19.             Intent intent =  new  Intent( this , TestActivity. class );    
  20.             startActivity(intent);    
  21.              break ;    
  22.          default :    
  23.              break ;    
  24.          }    
  25.     }       
  26. }   

上面的代碼中,主要是為“Start activity” 按鈕添加了 OnClickListener, 使得按鈕被點擊時執行 onClick() 方法, onClick() 方法中則利用了 Intent 機制,來啟動 TestActivity,關鍵的代碼是下面這兩行:

Intent intent = new Intent( this , TestActivity. class );

startActivity(intent);

這里定義 Intent 對象時所用到的是 Intent 的構造函數之一:

Intent ( Context packageContext, Class <?> cls)

兩個參數分別指定 Context 和 Class ,由于將Class 設置為 TestActivity.class,這樣便顯式的指定了TestActivity 類作為該Intent 的接收者,通過后面的startActivity() 方法便可啟動 TestActivity 。

TestActivity 的代碼更為簡單(定義 TestActivity類需要新建 TestActivity.java 文件,如果你是一個初學者,你需要學會如何在 Eclipse 或其他開發環境下添加一個新的類,這里不作詳述,請參考其他文檔),如下所示:

  1. package  com.tope.samples.intent.simple;    
  2. import  android.app.Activity;    
  3. import  android.os.Bundle;    
  4. public   class  TestActivity  extends  Activity {    
  5.      /**   Called   when   the   activity   is   first   created.   */   
  6.      @Override   
  7.      public   void  onCreate(Bundle savedInstanceState) {    
  8.          super .onCreate(savedInstanceState);    
  9.         setContentView(R.layout. test_activity );    
  10.     }    
  11. }    

可見 TestActivity僅僅是調用 setContentView 來顯示 test_activity.xml 中的內容而已。對于 test_activity.xml及本例中所用到其他 xml 文件這里不作多余說明。

如果我們僅僅是做上面的一些 工作,還不能達到利用 SimpleIntentTest 啟動 TestActivity的目的。事實上,這樣做會出現下面的 Exception ,導致程序退出。以下是利用 logcat 工具記錄的log 信息(省略了后半部分):
I/ActivityManager(569):Displayed activity com.tope.samples/.SimpleIntentTest: 3018 ms
I/ActivityManager(569):Starting activity: Intent { comp={com.tope.samples/com.tope.samples.TestActivity} }
D/AndroidRuntime(932):Shutting down VM
W/dalvikvm(932): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
E/AndroidRuntime(932):Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime(932):android.content.ActivityNotFoundException: Unable to find explicit activity class
 {com.tope.samples/com.tope.samples.TestActivity}; have you declared this activity in your AndroidManifest.xml?
E/AndroidRuntime(932):at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1480)
E/AndroidRuntime(932):at android.app.Instrumentation.execStartActivity(Instrumentation.java:1454)
E/AndroidRuntime(932):at android.app.Activity.startActivityForResult(Activity.java:2656)
E/AndroidRuntime(932):at android.app.Activity.startActivity(Activity.java:2700)
E/AndroidRuntime(932):at com.tope.samples.SimpleIntentTest.onClick(SimpleIntentTest.java:24)

從這些log 中我們可以看到點擊按鈕后 startActivity的調用過程,主要的原因是:“android.content.ActivityNotFoundException: Unable to find explicit activity class {com.tope.samples/com.tope.samples.TestActivity}; have you declared this activity in your AndroidManifest.xml?”

從這些log 我們可以看到原因是找不到 TestActivity這個 Activity ,并且 log 中還給出了提示:你是否在AndroidManifest.xml 中聲明了這個 Activity?解決問題的方法也就是按照提示在 AndroidManifest.xml 中增加TestActivity 的聲明,如下所示:

  1. <? xml   version = "1.0"   encoding = "utf-8" ?>   
  2. < manifest   xmlns:android = "http://schemas.android.com/apk/res/android"   
  3.        package = "com.tope.samples"   
  4.        android:versionCode = "1"   
  5.        android:versionName = "1.0" >   
  6.      < application   android:icon = "@drawable/icon"   android:label ="@string/app_name" >   
  7.          < activity   android:name = ".SimpleIntentTest"   
  8.                    android:label = "@string/app_name" >   
  9.              < intent-filter >   
  10.                  < action   android:name = "android.intent.action.MAIN"  />   
  11.                  < category   android:name ="android.intent.category.LAUNCHER"   />   
  12.              </ intent-filter >   
  13.          </ activity >   
  14.           < activity   android:name = ".TestActivity" />   
  15.      </ application >   
  16.      < uses-sdk   android:minSdkVersion = "3"   />   
  17. </ manifest >     

完成這個修改后再重新運行該程序,就一切都正常了。

別走開,下頁為您帶來Activity切換和隱式Intent

#p#

從AndroidManifest.xml修改的過程我們可以體會到, Intent 機制即使在程序內部且顯式指定接收者,也還是需要在 AndroidManifest.xml 中聲明 TestActivity。這個過程并不像一個簡單的函數調用,顯式的 Intent 也同樣經過了Android 應用程序框架所提供的支持,從滿足條件的 Activity 中進行選擇,如果不在 AndroidManifest.xml中進行聲明,則 Android 應用程序框架找不到所需要的 Activity。

請讀者通過我們的示例來逐步理解 AndroidManifest.xml在這個過程中所扮演的角色,這樣有利于理解 Intent的作用 ,及后面的 Intent Filter。當然,這個例子僅僅是開始,且看下文分解 。

不同應用程序之間的Activity切換

上面的例子我們所做的是在同 一應用程序中進行 Activity 的切換,那么在不同的應用程序中,是否也能這么做呢,答案是肯定的,不過對應的代碼要稍作修改。本例中我們需要兩個應用程序,可利用上例中 的SimpleIntentTest作為其中之一,另外還需要寫一個新的程序,來調用 SimpleIntentTest 應用程序中的 TestActivity。

我們新建程序 CrossIntentTest(注意不是新建一個類,如果是 Eclipse 環境,選擇 File->New->Project新建工程),其中只有一個 Activity ,其源代碼與 SimpleIntentTest.java 類似 :

  1. package  com.tope.samples.intent.cross;    
  2. import  android.app.Activity;    
  3. import  android.content.Intent;    
  4. import  android.os.Bundle;    
  5. import  android.view.View;    
  6. import  android.widget.Button;    
  7. public   class  CrossIntentTest  extends  Activity     
  8.      implements  View.OnClickListener{    
  9.      /**   Called   when   the   activity   is   first   created.   */   
  10.      @Override   
  11.      public   void  onCreate(Bundle savedInstanceState) {    
  12.          super .onCreate(savedInstanceState);    
  13.         setContentView(R.layout. main );    
  14.         Button startBtn = (Button)findViewById(R.id. start_activity );    
  15.         startBtn.setOnClickListener( this );    
  16.     }    
  17.      public   void  onClick(View v) {    
  18.          switch  (v.getId()) {    
  19.          case  R.id. start_activity :    
  20.             Intent intent =  new  Intent();    
  21.             intent.setClassName( "com.tope.samples.intent.simple" ,     
  22. .tope.samples.intent.simple.TestActivity" );    
  23.             startActivity(intent);    
  24.              break ;    
  25.          default :    
  26.              break ;    
  27.         }    
  28.     }       
  29. }   

注意比較它與 SimpleIntentTest的不同之處主要在于初始化 Intent 對象的過程:

  1. Intent intent =  new  Intent();    
  2. intent.setClassName( "com.tope.samples.intent.simple" ,     
  3.     "com.tope.samples.intent.simple.TestActivity" );    
  4. startActivity(intent);   

這里采用了 Intent 最簡單的不帶參數的構造函數 , 然后通過 setClassName() 函數來指定要啟動哪個包中的哪個 Activity, 而不是像上例中的通過 Intent ( Context packageContext, Class <?> cls) 這個構造函數來初始化Intent 對象,這是因為,要啟動的 TestActivity 與 CrossIntentTest 不在同一個包中 , 要指定 Class 參數比較麻煩 , 所以通常啟動不同程序的 Activity 時便采用上面的 setClassName() 的方式。除此之外,你也可以利用Android 提供的類似的 setComponent() 方法,具體使用方法請參考 Android SDK的文檔。

另外我們還需要修改SimpleIntentTest 程序中的 AndroidManifest.xml 文件,為 TestActivity 的聲明添加Intent Filter ,即將原來的

  1. <activity android:name = ".TestActivity" />  

修改為:

  1. <activity   android:name = ".TestActivity" >   
  2.      <intent-filter>   
  3.          <action   android:name = "android.intent.action.DEFAULT" />   
  4.      </intent-filter>   
  5. </activity >  

對于不同應用之間的 Activity 的切換,這里需要在 Intent Filter中 設置至少一個 Action,否則其他的應用將沒有權限調用這個 Activity 。這里我們開始接觸 Intent Filter和 Action 這些概念了,讀者應該可以感覺到,設置Intent Filter 和 Action 主要的目的,是為了讓其他需要調用這個 Activity 的程序能夠順利的調用它。除了Action之外, Intent Filter 還可以設置 Category 、 Data等,用來更加精確的匹配 Intent 與 Activity。

隱式Intent(Implicit Intent)

如果 Intent機制僅僅提供上面的顯式 Intent用法的話,這種相對復雜的機制似乎意義并不是很大。確實,Intent 機制更重要的作用在于下面這種隱式的 Intent ,即Intent的發送者不指定接收者,很可能不知道也不關心接收者是誰,而由Android框架去尋找最匹配的接收者。

最簡單的隱式 Intent

我們先從最簡單的例子開始。 下面的 ImplicitIntentTest 程序用來啟動 Android 自帶的打電話功能的 Dialer 程序。

ImplicitIntentTest 程序只包含一個java 源文件 ImplicitIntentTest.java,代碼如下所示:

  1. package  com.tope.samples.intent.implicit;    
  2. import  android.app.Activity;    
  3. import  android.content.Intent;    
  4. import  android.os.Bundle;    
  5. import  android.view.View;    
  6. import  android.widget.Button;    
  7. public   class  ImplicitIntentTest  extends  Activity         
  8.      implements  View.OnClickListener{    
  9.      /**   Called   when   the   activity   is   first   created.   */   
  10.      @Override   
  11.      public   void  onCreate(Bundle savedInstanceState) {    
  12.          super .onCreate(savedInstanceState);    
  13.         setContentView(R.layout. main );    
  14.         Button startBtn = (Button)findViewById(R.id. dial );    
  15.         startBtn.setOnClickListener( this );    
  16.     }    
  17.      public   void  onClick(View v) {    
  18.          switch  (v.getId()) {    
  19.          case  R.id. dial :    
  20.             Intent intent =  new  Intent(Intent. ACTION_DIAL );    
  21.             startActivity(intent);    
  22.              break ;    
  23.          default :    
  24.              break ;    
  25.         }    
  26.     }       
  27. }    

該程序在Intent 的使用上,與上節中的使用方式有很大的不同,即根本不指定接收者,初始化 Intent 對象時,只是傳入參數,設定 Action為 Intent.ACTION_DIAL :

Intent intent = new Intent(Intent. ACTION_DIAL );

startActivity(intent);

這里使用的構造函數的原型如下:

Intent ( String action);

這里讀者可暫時將action理解為描述這個 Intent 的一種方式,這種使用方式看上去比較奇怪, Intent 的發送者只是指定了 Action為 Intent.ACTION_DIAL ,那么怎么找到接收者呢?來看下面的例子。

增加一個接收者

事實上接收者如果希望能夠接收某些 Intent ,需要像上節例子中一樣,通過在 AndroidManifest.xml中增加Activity 的聲明,并設置對應的 Intent Filter 和 Action ,才能被 Android 的應用程序框架所匹配。為了證明這一點,我們修改上一 節 SimpleIntentTest 程序中的 AndroidManifest.xml 文件,將 TestActivity 的聲明部分改為:

  1. <activity   android:name = ".TestActivity" >   
  2.              <intent-filter >   
  3.                  <action   android:name = "android.intent.action.DEFAULT"   />   
  4.                  <action   android:name = "android.intent.action.DIAL"   />   
  5.                  <category   android:name = "android.intent.category.DEFAULT"  />   
  6.              </intent-filter >   
  7.     </activity >    

這個截圖中的第二幅表示可以選擇 Dialer 或者 SimpleIntentTest 程序來完成 Intent.ACTION_DIAL ,也就是說,針對 Intent.ACTION_DIAL, Android 框架找到了兩個符合條件的 Activity,因此它將這兩個 Activity 分別列出,供用戶選擇。

回過頭來看我們是怎么做到這一點的。我們僅僅在 SimpleIntentTest 程序的 AndroidManifest.xml 文件中增加了下面的兩行:

  1. <action android:name = "android.intent.action.DIAL" />   
  2.  category android:name = "android.intent.category.DEFAULT"/>  

這兩行修改了原來的 Intent Filter,這樣這個 Activity 才能夠接收到我們發送的 Intent 。我們通過這個改動及其作用,可以進一步理解隱式 Intent, Intent Filter 及 Action, Category 等概念—— Intent 發送者設定 Action 來說明將要進行的動作,而 Intent 的接收者在 AndroidManifest.xml 文件中通過設定 Intent Filter來聲明自己能接收哪些Intent 。

責任編輯:閆佳明 來源: jizhuomi
相關推薦

2014-07-15 10:16:02

AndroidIntent

2013-01-10 14:54:48

Android開發組件Intent

2017-03-29 09:08:25

Spring筆記

2015-12-16 10:30:18

前端開發指南

2015-09-18 16:55:45

云計算

2013-03-28 09:07:37

Android開發Intent機制

2009-12-30 17:30:43

EPON技術

2009-04-03 08:21:37

AndroidGoogle移動OS

2013-01-10 15:36:44

Android開發組件Intent

2010-01-25 16:52:22

Android Int

2015-11-17 09:30:23

程序員招聘建議

2016-01-28 14:41:06

CC++編碼

2011-05-30 14:00:35

Android Activity Intent

2020-04-14 10:50:47

FlutterGithub

2016-01-07 10:26:49

全球程序員研究報告

2011-12-15 10:49:57

Broadcom汽車以太網

2013-06-27 15:14:56

搜狗手機地圖

2012-05-18 11:40:40

神舟筆記本

2018-03-27 09:31:21

數據庫MySQL線程池

2015-06-23 17:35:42

甲骨文云計算
點贊
收藏

51CTO技術棧公眾號

999久久欧美人妻一区二区| 免费看a级黄色片| 成年永久一区二区三区免费视频| 亚洲va韩国va欧美va精品| 91免费网站视频| 亚洲高清影视| 欧美激情精品久久久久久大尺度 | a级精品国产片在线观看| 国产精品午夜av在线| 伊甸园亚洲一区| 麻豆一区二区在线观看| 免费观看一级欧美片| 日韩一区二区在线观看视频播放| 免费观看v片在线观看| 日本一区二区三区国色天香| 在线观看欧美一区| 性一交一乱一区二区洋洋av| 国产免费一区二区三区在线能观看 | 91精品办公室少妇高潮对白| 99热热99| 日本一区二区视频在线| 97超碰在线人人| 麻豆视频一区二区| 日韩欧美一区二区三区四区 | 国产国产国产国产国产国产| xfplay精品久久| 黄网站欧美内射| 国产一区二三区好的| 日韩高清在线播放| 日韩综合在线视频| 秋霞毛片久久久久久久久| 亚洲一本视频| 国新精品乱码一区二区三区18| 香蕉精品视频在线观看| 国产在线观看精品一区二区三区| 小嫩嫩12欧美| 国产经典一区二区| 日韩在线二区| 91国产在线播放| 欧美三级在线| 国产亚洲情侣一区二区无| 欧美人成在线| 国产一区二区无遮挡| 日韩亚洲在线| 精品蜜桃一区二区三区| 日本伊人午夜精品| av日韩在线看| 91蜜桃免费观看视频| 黄色免费网址大全| 一区二区三区精密机械公司| 天天在线女人的天堂视频| 欧美日韩aaa| 日本无删减在线| 国产亚洲精品久久久| 在线成人免费| 国产91免费看片| 亚洲高清久久| 自拍另类欧美| 国产丝袜欧美中文另类| 黄色免费观看网站| 色伊人久久综合中文字幕| aa在线视频| 亚洲系列中文字幕| 欧美成a人免费观看久久| 91香蕉电影院| 国产在线视频一区二区| 88av.com| 岛国精品视频在线播放| 色综合999| 久久人人看视频| 欧美特黄视频| 国产资源在线免费观看| 国产精品国产三级国产aⅴ中文| ga∨成人网| 亚洲第一精品电影| 欧美9999| 欧美精品第一页在线播放| 日韩av免费大片| 精品亚洲一区二区三区四区五区高| 国产精品视频久久一区| 国产手机免费视频| 欧美日韩黄色大片| 欧美magnet| 国产精品热视频| 毛片av一区二区| aaa免费看大片| 欧美电视剧在线看免费| 精品女人视频| 亚洲a∨一区二区三区| 国产精品女同一区二区三区| 在线看免费av| 欧美国产在线视频| 99亚洲伊人久久精品影院红桃| 天堂…中文在线最新版在线| 91国偷自产一区二区三区成为亚洲经典| 亚洲涩涩在线| 国产欧美日韩专区发布| 久久99久久精品| 亚洲一区二区三区精品动漫| 欧美日本一区二区三区四区| 成人国产一区| 欧美一级视频免费看| 亚洲精品亚洲人成人网在线播放| av免费在线网站| 91精品国产91久久久久| 日韩精品欧美精品| 亚洲网站情趣视频| 日韩在线播放视频| 99热这里只有成人精品国产| www午夜视频| 亚洲免费影视第一页| 一区二区不卡| 亚洲污视频在线观看| 亚洲成人中文字幕| 久久一本综合| 中文字幕在线观看第三页| 精品国产91亚洲一区二区三区婷婷| 91精品在线免费视频| v天堂福利视频在线观看| 国色天香2019中文字幕在线观看| 成年人免费网站| 亚洲娇小xxxx欧美娇小| 成人vr资源| 久久久久久久久久网| 91精品啪在线观看国产60岁| 精品在线观看入口| 日本免费不卡一区二区| 亚洲电影免费观看| 精品1区2区3区4区| 最猛黑人系列在线播放| 午夜精品久久久久久久99热| 国产在线视频精品一区| 国产福利视频在线| 91在线视频导航| 亚洲精品写真福利| 97精品久久| 日韩激情免费视频| 在线观看91久久久久久| 久久精品999| 欧美黄色小说| 国产精品嫩草影院一区二区| 亚洲欧美综合另类在线卡通| 日韩欧美激情| 桥本有菜av在线| 精品久久久久久久久久久久包黑料 | 中文字幕av资源一区| 日韩三区免费| 黄黄视频在线观看| 亚洲精品福利视频| 蜜臀av性久久久久蜜臀av麻豆| 91porn在线观看| 国内成+人亚洲| 制服丝袜中文字幕亚洲| 亚洲九九精品| 毛片在线播放a| 开心色怡人综合网站| 日韩色视频在线观看| 亚洲精品专区| caopeng在线| 欧美日韩一区二区三区在线视频 | 欧美在线三区| 麻豆导航在线观看| 国产精品手机在线| 欧美精品乱人伦久久久久久| 亚洲激情av| 亚洲精品天堂| 一级黄色免费在线观看| 亚洲第一精品夜夜躁人人爽| 久久99国产精品久久| 另类专区亚洲| 日本新janpanese乱熟| 97在线精品视频| 亚洲成av人片在www色猫咪| 五月天激情综合网| 国产三级在线播放| 亚洲一区精彩视频| 最近免费中文字幕视频2019| 成人一道本在线| 日本国产一区| 四虎国产精品成人免费4hu| 成人免费看吃奶视频网站| 精品国产乱码久久久久久影片| av色综合久久天堂av综合| 青青草成人影院| 深夜在线视频| 国产对白在线正在播放| 中文字幕免费在线不卡| 国产成人综合精品在线| 欧美成人精品高清在线播放| 中文字幕精品在线不卡| 日韩精品五月天| 日韩国产欧美| www欧美在线观看| 欧美尤物美女在线| jizz大全欧美jizzcom| 亚洲精品国产精品国自产观看| 国产91精品高潮白浆喷水| 亚洲国产精品999| 色婷婷久久久亚洲一区二区三区| 国产成人免费高清|