Intent和Activity的另一种启动方法startActivityForResult()

Intent主要用来启动其他的Activity、Service、Broadcast


显示Intent与隐式Intent

Intent intent = new Intent();
intent.setClass(Context packageContext, OtherActivity.class);	//显式intent,指明确指出此intent是启动哪个activity.
startActivity(intent);

<span style="background-color: rgb(255, 255, 255);">Intent intent = new Intent();
intent.setAction(Intent.ACTION_NEW);	//隐式intent是指并没有指出要启动哪个activity,而要系统自动去判断并启动匹配的activity
startActivity(intent);</span>


显式Intent

有两种方式来显示的指示要启动的Activity:

方式一:(通过setClassName)

Intent intent = new Intent();
//表示希望启动com.example.test_permission包中的com.example.test_permission.MainActivity
intent.setClassName("com.example.test_permission", "com.example.test_permission.MainActivity");
startActivity(intent);
方式二:(通过SetClass)
Intent intent = new Intent();
intent.setClass(Context packageContext, OtherActivity.class);
startActivity(intent);

注意:Context代表访问该应用环境信息的接口,而包名是应用的唯一标识,所以它们有一一对应的关系。


隐式intent

public class Intent implements Parcelable, Cloneable {   //... private String mAction;
    private Uri mData;
    private String mType;
    private String mPackage;
    private ComponentName mComponent;
    private int mFlags;
    private HashSet<String> mCategories;
    private Bundle mExtras;
    private Rect mSourceBounds;

从上面源码可以看出,Intent对象包含Data、Type、Component、Flag、Category、Action、Extra


Action、Category

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
Activity的intent-filter的子元素代表了该Activity所能响应的Intent,一旦匹配就可以激活该Activity。
注意:
1.intent-filter中通常包括action(0~N个)、category(0~N个)、data(0~1个)
2.intent-filter的子元素也可以使<service.../>、<receiver.../>
3.intent-filter代表了该组件所能满足的要求,只要能满足的要求大于等于intent的要求,就可以启动


Action:该activity可以执行的一个“抽象”动作

该标识用来说明这个activity可以执行哪些动作,所以当隐式intent传递过来action时,如果跟这里<intent-filter>所列出的任意一个匹配的话,就说明这个activity是可以完成这个intent的意图的,可以将它激活

注意
1. 一个activity可以有多个action,如果Intent请求的Action和<intent-filter>中个任意一条<action>匹配, 那么该Intent就可以激活该activity(前提是除了action的其它项也要通过)
2.如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent-filter>匹配,所以最好至少包括一个action
3.如果仅指定某个action,而多个activity都具有这个action的话,系统会列出列表供用户选择执行哪一个activity.
4.如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个Intent请求就将顺利地通过<intent-filter>的行为测试。

常用action有:

ACTION_CALL activity 启动一个电话.
ACTION_EDIT activity 显示用户编辑的数据.
<span style="color:#ff0000;">ACTION_MAIN</span> activity 作为Task中第一个Activity启动,即应用程序入口
ACTION_SYNC activity 同步手机与数据服务器上的数据.
ACTION_BATTERY_LOW broadcastreceiver 电池电量过低警告.
ACTION_HEADSET_PLUG broadcastreceiver 插拔耳机警告
ACTION_SCREEN_ON broadcastreceiver 屏幕变亮警告.
<span style="color:#ff0000;">ACTION_VIEW</span> Activity 查看指定数据



Category:指定当前动作(Action)被执行的环境,为Action增加额外的附加类别信息

即这个activity在哪个环境中才能被激活。不属于这个环境的,不能被激活。

常用category:

     <span style="color:#ff0000;">CATEGORY_DEFAULT</span>:Android系统中默认的执行方式,按照普通Activity的执行方式执行。表示所有intent都可以激活它 

    CATEGORY_HOME:设置该组件为Home Activity。

    CATEGORY_PREFERENCE:设置该组件为Preference。 

    <span style="color:#ff0000;">CATEGORY_LAUNCHER</span>:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常与入口ACTION_MAIN配合使用。 

    CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。表示该activity只能用来浏览网页。 

    CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。


例子:假如想要返回系统的Home桌面,除了按Home键,也可以通过intent配置

Intent intent=new Intent();
intent.setAction(Intent.<span style="color:#ff6600;">ACTION_MAIN</span>);
intent.addCategory(Intent.<span style="color:#ff6600;">CATEGORY_HOME</span>);
startActivity(intent);
注意:

如果该activity想要通过隐式intent方式激活,那么不能没有任何category设置,至少包含一个android.intent.category.DEFAULT,因为当Intent被创建时,默认Category属性值为Intent.CATEGORY_DEFAULT。



Data、Type

Data  Action属性执行时要操作的数据

在目标<data/>标签中包含了以下几种元素,他们定义了url的匹配规则:

  • android:scheme 匹配url中的前缀,指定数据的协议部分,除了“http”、“https”、“tel”...之外,我们可以定义自己的前缀
  • android:host 匹配url中的主机名部分,如“google.com”,如果定义为“*”则表示任意主机名
  • android:port 匹配url中的端口
  • android:path 匹配url中的路径
  • android:mimeType Type属性,指定该Data属性所指定的Uri的数据类型(MIME类型),允许使用通配符,而且可以是自定义的MIME类型,只要符合abc/xyz的格式的字符串即可
<activity android:name=".TargetActivity">
<span style="white-space:pre">	</span><intent-filter>
<span style="white-space:pre">		</span><action android:name="com.scott.intent.action.TARGET"/>
<span style="white-space:pre">		</span><category android:name="android.intent.category.DEFAULT"/>
<span style="white-space:pre">		</span><data android:scheme="scott" android:host="com.scott.intent.data" android:port="7788" android:path="/target"/>
<span style="white-space:pre">	</span></intent-filter>
</activity>

注意

1.只有<data.../>标签中指定的内容和Intent中携带的Data完全一致时,当前活动才能被激活。如果其它条件都足以激活该Activity,但intent却没有传进来指定类型的Data时,就不能激活该activity。所以想要启动上面的Activity,除了设置action外还要设置Data

2.Data属性与Type属性会相互覆盖,后这设置的会覆盖先设置的,如果想要同时存在,则要用setDataandType()方法


例子:打开浏览器,访问一个网页,action和data结合使用

Intent intent=new Intent();
intent.setAction(Intent.<span style="color:#ff6600;">ACTION_VIEW</span>);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);


Extras

这个参数不参与匹配activity,而仅作为额外数据传送到另一个activity中,接收的activity可以将其取出来。这些信息并不是激活这个activity所必须的。也就是说激活某个activity与否只上action、data、catagory有关,与extras无关。而extras用来传递附加信息,诸如用户名,用户密码什么的。

可通过putXX()和getXX()方法存取信息;也可以通过创建Bundle对象,再通过putExtras()和getExtras()方法来存取。

putXXX()方法的本质仍然是通过Bundle实现

   public Intent putExtra(String name, long value) {
        if (mExtras == null) {
            mExtras = new <span style="color:#ff0000;">Bundle()</span>;
        }
        mExtras.<span style="color:#ff0000;">putLong</span>(name, value);
        return this;
    }
而传递一个Bundle:

public Intent putExtra(String name, Bundle value) {
        if (mExtras == null) {
            mExtras = new <span style="color:#ff0000;">Bundle</span>();
        }
        mExtras.<span style="color:#ff0000;">putBundle</span>(name, value);
        return this;
    }
归根结底都是通过Bundle来实现数据封装。而Bundle则是通过Map的数据结构来存储数据。

关于Bundle则是实现了Parcelable接口的类,通过上面提到的HashMap和一个Parcel来存储数据。


Intent源码6700多行代码,但真正核心代码 就那么几百行,大部分都用来定义常量字符串了 

先来看一下

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class Intent implements Parcelable, Cloneable  

没错,它还实现了cloneable接口,但平常我们很少会用到它,其实现方法为: 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * Copy constructor. 
  3.  */  
  4. public Intent(Intent o) {  
  5.     this.mAction = o.mAction;  
  6.     this.mData = o.mData;  
  7.     this.mType = o.mType;  
  8.     this.mPackage = o.mPackage;  
  9.     this.mComponent = o.mComponent;  
  10.     this.mFlags = o.mFlags;  
  11.     if (o.mCategories != null) {  
  12.         this.mCategories = new HashSet<String>(o.mCategories);  
  13.     }  
  14.     if (o.mExtras != null) {  
  15.         this.mExtras = new Bundle(o.mExtras);  
  16.     }  
  17.     if (o.mSourceBounds != null) {  
  18.         this.mSourceBounds = new Rect(o.mSourceBounds);  
  19.     }  
  20.     if (o.mSelector != null) {  
  21.         this.mSelector = new Intent(o.mSelector);  
  22.     }  
  23.     if (o.mClipData != null) {  
  24.         this.mClipData = new ClipData(o.mClipData);  
  25.     }  
  26. }  
  27.   
  28. @Override  
  29. public Object clone() {  
  30.     return new
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值