Android开发学习笔记:浅谈显示Intent和隐式Intent

Intent寻找目标组件的两种方式:

·       显式Intent:通过指定Intent组件名称来实现的,它一般用在知道目标组件名称的前提下,一般是在相同的应用程序内部实现的。

·       隐式Intent:通过Intent Filter来实现的,它一般用在没有明确指出目标组件名称的前提下,一般是用于在不同应用程序之间。

.显式Intent

   一般情况下,一个Android应用程序中需要多个屏幕,即是多个Activity类,并且在这些Activity之间进行切换通过Intent机制来实现的。在同一个应用程序中切换Activity时,我们通常都知道要启动的Activity具体是哪一个,因此常用显式的Intent来实现的。

    下面的例子是在同一应用程序中MainActivity启动SecondActivity,下面的代码中,主要是为“转到SecondActivity”按钮添加了OnClickListener,使得按钮被点击时执行onClick()方法,onClick()方法中则利用了Intent机制,来启动SecondActivity,关键的代码是22~25行。

main.xml

1.    <?xmlversion="1.0"encoding="utf-8"?>

2.    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

3.        android:orientation="vertical"

4.        android:layout_width="fill_parent"

5.        android:layout_height="fill_parent"

6.        >

7.        <TextView   

8.            android:layout_width="fill_parent"  

9.            android:layout_height="wrap_content"  

10.         android:text="@string/hello1"

11.          />

12.     <Button  

13.          android:id="@+id/btn"

14.         android:layout_width="wrap_content"  

15.          android:layout_height="wrap_content"  

16.         android:text="转到SecondActivity"

17.          />

18. </LinearLayout>

second.xml

1.    <?xmlversion="1.0"encoding="utf-8"?>

2.    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

3.        android:orientation="vertical"

4.        android:layout_width="fill_parent"

5.        android:layout_height="fill_parent"

6.        >

7.        <TextView   

8.            android:layout_width="fill_parent"  

9.            android:layout_height="wrap_content"  

10.         android:text="@string/hello2"

11.          />

12.     <Button  

13.          android:id="@+id/secondBtn"

14.         android:layout_width="wrap_content"  

15.          android:layout_height="wrap_content"  

16.         android:text="返回"

17.          />

18. </LinearLayout>

MainActivity.java

1.    package com.android.test.activity; 

2.     

3.    importandroid.app.Activity; 

4.    importandroid.content.Intent; 

5.    importandroid.os.Bundle; 

6.    importandroid.view.View; 

7.    importandroid.view.View.OnClickListener; 

8.    importandroid.widget.Button; 

9.     

10. publicclass MainActivity extends Activity { 

11.      private Button btn; 

12.     @Override

13.      publicvoid onCreate(BundlesavedInstanceState) { 

14.         super.onCreate(savedInstanceState); 

15.          setContentView(R.layout.main); 

16.           

17.          btn =(Button)findViewById(R.id.btn); 

18.         //响应按钮btn事件 

19.          btn.setOnClickListener(new OnClickListener() {       

20.             @Override

21.              publicvoid onClick(View v){ 

22.                 //显示方式声明Intent,直接启动SecondActivity 

23.                  Intent it = new Intent(MainActivity.this,SecondActivity.class); 

24.                 //启动Activity  

25.                  startActivity(it);           

26.             } 

27.          }); 

28.     } 

29.  }

SecondActivity.java

1.    packagecom.android.test.activity; 

2.     

3.    importandroid.app.Activity; 

4.    import android.content.Intent; 

5.    importandroid.os.Bundle; 

6.    importandroid.view.View; 

7.    importandroid.view.View.OnClickListener; 

8.    importandroid.widget.Button; 

9.     

10. publicclass SecondActivity extends Activity { 

11.      private Button secondBtn; 

12.     @Override

13.      protectedvoid onCreate(BundlesavedInstanceState) { 

14.         super.onCreate(savedInstanceState); 

15.          setContentView(R.layout.second); 

16.           

17.          secondBtn=(Button)findViewById(R.id.secondBtn);     

18.         //响应按钮secondBtn事件 

19.          secondBtn.setOnClickListener(new OnClickListener() {                     

20.             @Override

21.              publicvoid onClick(View v){ 

22.                 //显示方式声明Intent,直接启动MainActivity 

23.                  Intent intent = new Intent(SecondActivity.this,MainActivity.class); 

24.                 //启动Activity  

25.                  startActivity(intent);               

26.             } 

27.          }); 

28.     } 

29.  }

AndroidManifest.xml清单文件,16~18行为SecondActivity在清单文件里的声明

1.    <?xmlversion="1.0"encoding="utf-8"?>

2.    <manifestxmlns:android="http://schemas.android.com/apk/res/android"

3.          package="com.android.test.activity"

4.          android:versionCode="1"

5.          android:versionName="1.0">

6.        <uses-sdkandroid:minSdkVersion="10"/>

7.     

8.        <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">

9.            <activityandroid:name=".MainActivity"

10.                   android:label="@string/app_name">

11.              <intent-filter>

12.                 <actionandroid:name="android.intent.action.MAIN"/>

13.                  <categoryandroid:name="android.intent.category.LAUNCHER"/>

14.             </intent-filter>

15.          </activity>

16.         <activityandroid:name=".SecondActivity"

17.                    android:label="@string/app_name">

18.         </activity>

19.      </application>

20. </manifest>

效果图:

.隐式Intent

   下面是同一应用程序中的Activity切换的例子,需要AndroidManifest.xml中增加Activity的声明,并设置对应的Intent Filter和Action,才能被Android的应用程序框架所匹配。

MainActivity.java

1.    packagecom.android.change.activity; 

2.     

3.    importandroid.app.Activity; 

4.    importandroid.content.Intent; 

5.    importandroid.os.Bundle; 

6.    importandroid.view.View; 

7.    importandroid.view.View.OnClickListener; 

8.    importandroid.widget.Button; 

9.     

10. publicclass MainActivity extends Activity { 

11.      private Button btn; 

12.  

13.      @Override

14.     publicvoid onCreate(Bundle savedInstanceState) { 

15.          super.onCreate(savedInstanceState); 

16.         setContentView(R.layout.main); 

17.   

18.         btn = (Button)findViewById(R.id.btn); 

19.          // 响应按钮btn事件 

20.         btn.setOnClickListener(new OnClickListener() { 

21.              @Override

22.             publicvoid onClick(View v) { 

23.                  //实例化Intent  

24.                 Intent it = new Intent(); 

25.                  //设置IntentAction属性 

26.                 it.setAction("com.android.activity.MY_ACTION"); 

27.                  // 启动Activity  

28.                 startActivity(it);  

29.              } 

30.       });   

31.      } 

32. 

SecondActivity.java

1.    packagecom.android.change.activity; 

2.     

3.    importandroid.app.Activity; 

4.    importandroid.os.Bundle; 

5.     

6.    publicclass SecondActivity extends Activity { 

7.     

8.        @Override

9.        protectedvoid onCreate(Bundle savedInstanceState) { 

10.         super.onCreate(savedInstanceState); 

11.          setContentView(R.layout.second); 

12.     } 

13. 

main.xml

1.    <?xmlversion="1.0"encoding="utf-8"?>

2.    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

3.        android:orientation="vertical"  

4.        android:layout_width="fill_parent"

5.        android:layout_height="fill_parent"

6.        >

7.        <TextView  

8.            android:layout_width="fill_parent"

9.            android:layout_height="wrap_content"  

10.         />

11.      <Button  

12.         android:id="@+id/btn"  

13.          android:layout_width="wrap_content"

14.         android:layout_height="wrap_content"

15.          android:text="转到SecondActivity"  

16.         />

17.  </LinearLayout>

seond.xml

1.    <?xmlversion="1.0"encoding="utf-8"?>  

2.    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  

3.       android:orientation="vertical"  

4.       android:layout_width="fill_parent"  

5.       android:layout_height="fill_parent"  

6.       >  

7.       <TextView     

8.            android:layout_width="fill_parent"    

9.            android:layout_height="wrap_content"    

10.         android:text="@string/second"  

11.          />  

12. </LinearLayout>

    AndroidManifest.xml文件的18,19行修改了Intent Filter,这样SecondActivity才能够接收到MainActivity发送的Intent。因为在MainActivity的Intent发送的动作为"com.android.activity.MY_ACTION",而在18行里,SecondActivity设置的Action也为"com.android.activity.MY_ACTION",这样就能进行匹配。

1.    <?xmlversion="1.0"encoding="utf-8"?>

2.    <manifestxmlns:android="http://schemas.android.com/apk/res/android"

3.          package="com.android.change.activity"

4.          android:versionCode="1"

5.          android:versionName="1.0">

6.        <uses-sdkandroid:minSdkVersion="10"/>

7.     

8.        <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">

9.            <activityandroid:name=".MainActivity"

10.                   android:label="@string/app_name">

11.              <intent-filter>

12.                 <actionandroid:name="android.intent.action.MAIN"/>

13.                  <categoryandroid:name="android.intent.category.LAUNCHER"/>

14.             </intent-filter>

15.          </activity>

16.         <activityandroid:name=".SecondActivity">                

17.          <intent-filter>  

18.             <action  android:name = "com.android.activity.MY_ACTION"  />  

19.              <categoryandroid:name = "android.intent.category.DEFAULT"  />  

20.          </intent-filter>      

21.          </activity>         

22.     </application>

23.  </manifest>

效果图:

 

 

对于显示Intent,Android不需要再去做解析,因为目标组件很明确。Android需要解析的是隐式Intent,通过解析,将Intent映射给可以处理该Intent的Activity,Service等。Intent的解析机制主要是通过查找已经注册在AndroidManifest.xml中的所有IntentFilter以及其中定义的Intent,最终找到匹配的Intent。

 

 

1.       显示匹配(explicit intent

对于明确指出了目标组件名称的Intent,我们称之为“显式Intent”

1)同一个应用程序中的Activity切换

Intent i=newIntent(Test.this,TestB.class);

This.startActivity(i);

2)不同应用程序之间的Activity切换

Intent i=newIntent;

i.setClassName(“com.tope.samples.intent.simple”,”com.tope.samples.intent.simple.TestActivity”);

This.startActivity(i);

注意:对于不同应用之间的Activity的切换,这里需要在Intent Filter中设置至少一个Action,否则其他的应用将没有权限调用这个Activity。

2.       隐式匹配(implicit intent

对于没有明确指出目标组件名称的Intent,则称之为“隐式 Intent”。 Android系统使用IntentFilter 来寻找与隐式Intent相关的对象。

显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式Intent更 多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。隐式Intent恰恰相反,它不会用组件名称定义需要 激活的目标组件,它更广泛地用于在不同应用程序之间传递消息。

在显式Intent消息中,决定目标组件的唯一 要素就是组件名称,因此,如果你的Intent中已经明确定义了目标组件的名称,那么你就完全不用再定义其他Intent内容。而对于隐式Intent则 不同,由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。具体的选择方法 是:Android将Intent的请求内容和一个叫做IntentFilter的过滤器比较,IntentFilter中包含系统中所有可能的待选组 件。如果IntentFilter中某一组件匹配隐式Intent请求的内容,那么Android就选择该组件作为该隐式Intent的目标组件。

Android如何知道应用程序能够处理某种类型的Intent请求呢?这需要应用程序在Android-Manifest.xml中声明自己所含 组件的过滤器(即可以匹配哪些Intent请求)。一个没有声明Intent-Filter的组件只能响应指明自己名字的显式Intent请求,而无法响 应隐式Intent请求。而一个声明了IntentFilter的组件既可以响应显式Intent请求,也可以响应隐式Intent请求。在通过和 IntentFilter比较来解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准。

1)  Action:使用android:name特性来指定对响应的动作名。

2)  Data/type:该标签允许你指定组件能作用的数据。

3)  Category:使用android:category属性来指定在什么样的环境下动作才被响应。每个IntentFilter标签可以包含多个category标签。

4)  Extras和flag:在解析收到Intent时是并不起作用的

 

举例:

1)启动android自带的打电话功能的Dialer程序。

Intent intent=new Intent(Intent.ACTION_DIAL);

startActivity(intent);

也可以为另外一个Activity加上

<action android:name="android.intent.action.DIAL" />

<category android:name="android.intent.category.DEFAULT" />

这样在匹配Action_DIAL时,会出现选择框,让用户选择是打开Dialer程序还是用户自定义的Activity。

理论上来说,如果intent不指定category,那么无论intent filter的内容是什么都应该是匹配的。但是,如果是implicitintent,android默认给加上一个CATEGORY_DEFAULT,这样的话如果intent filter中没有android.intent.category.DEFAULT这个category的话,匹配测试就会失败。所以,如果你的 activity支持接收implicit intent的话就一定要在intent filter中加入android.intent.category.DEFAULT。

例外情况是:android.intent.category.MAIN和android.intent.category.LAUNCHER的filter中没有必要加入android.intent.category.DEFAULT,当然加入也没有问题。

另外:android.intent.action.MAIN决定应用程序最先启动的Activityandroid.intent.category.LAUNCHER决定应用程序是否显示在程序列表里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值