Intent 全面理解

介绍

        Intent的字面解释为“意图”。

        众所周知,在Android中一个应用程序是由四大组件来协调完成工作的,而他们之间的通讯工作主要是通过Intent来完成的。Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,可以将Intent理解为:不同组件之间通讯的“媒介”,专门提供组件之间互相调用的信息。

    



Intent启动组件的方法:
                
                    通过Intent启动Activity、Service、BroadCast的方法
 

组件名称

方法名称

方法解释

 

Activity

StartActivity()

启动一个新的Activity,但不需要接收返回值

startActivityForResult()

启动一个新的Activity,且可以接收目的Activity发送的返回值

 

Service

startService( )

请求启动给定的Service

bindService( )

连接给定的Service,如果没有则需要创建

 

 

 

BroadCast

sendBroadcast()

Intent通过普通广播的形式发送出去

sendOrderedBroadcast()

发送有序广播,广播接收器的优先级高,则能够先接收到广播,高级别的接收器可以拦截广播,也可以向广播中传入参数

sendStickyBroadcast()

通过这种方式发送出去的广播会一直滞留(等待),以便接收器能够迅速接收到广播




Intent的属性

     1、Component属性

             要启动的组件名称,在创建Intent的时候是可选的,但是它是显式Intent的重要标志,有它就意味着只有Component name匹配上的那个组件才能接收你发送出来的显示intent。如果不写那么你创建的Intent就是隐式的,系统会根据这个intent的其他信息(比如:actiondatacategory)来确定哪些组件来接收这个intent,所以如果你想明确的启动哪个组件,就通过component name来指定。
       IntentComponent属性需要接受一个ComponentName对象。创建一个Component对象需要指定包名和类名,可以唯一的确定一个组件类。这样应用程序可以根据给定的组件类去启动特定的组件。

        Component的三种构造函数:

            Component(String pkgName,String activityName);

                    //ComponentName componentName=new ComponentName("com.wyx.chapter_1","com.wyx.chapter_1.ThirdActivity");

            Component(Context context, String activityName);

                   // ComponentName componentName=new ComponentName(this,"com.launchmodetest.SecondActivity");

            Component(Context context,Class<?> cls);

                   //ComponentName componentName=new ComponentName(this,SecondActivity.class);

            为Intent设置Component属性: intent.setComponent(componentName);这样Intent就可以唯一确定所要启动的是哪一个组件。
        Intent中也存在三个方法也能实现ComponentName的效果
            Intent. setClassName(String packageName, String className);
                     //intent.setClassName("com.wyx.chapter_1","com.wyx.chapter_1.ThirdActivity");
            Intent. setClassName(Context packageContext, String className);
                     //intent.setClassName(ThirdActivity.this,"com.launchmodetest.SecondActivity");
            Intent. setClass(Context packageContext, Class<?> cls);
                    // intent.setClass(this,SecondActivity.class);
        需要注意的一点是:在使用String来代表组件名称时一定要是 组件的全称,如 "com.wyx.chapter_1.ThirdActivity"。

     2、Action属性
        
             Action是指Intent要完成的动作,是一个字符串常量。
            Android中提供了一些通用的Action,当然我们也可以自定义Action。
                常用Action:
Action标示
含义
ACTION_CALL
activity 启动一个电话.
ACTION_MAIN
activity 作为Task中第一个Activity启动
ACTION_BATTERY_LOW
broadcast receiver 电池电量过低警告.
ACTION_SCREEN_ON
broadcast receiver 屏幕变亮警告.
ACTION_HEADSET_PLUG
broadcast receiver 插拔耳机警告

     3、Category属性

             提供将要执行的action的额外信息,一般在隐式地启动activity时需要用到。

     4、Data属性

            通常用于向Action属性提供操作的数据。
            该属性值为一个Uri对象。
                Uri,全称 通用资源标志符(Universal Resource Identifier, 简称"URI")。Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。Uri字符串总满足这样的格式:scheme://host:port/path,比如某个图片资源的uri, content://media/external/images/media/4。
                Uri的结构中,scheme:URI的模式,比如http、file、content等,如果URI中没有指定scheme,那么整个URI的其他参数无效,即该URI无效。
                                      host:URI的主机名,比如www.baidu.com,如果URI中没有指定scheme,那么整个URI的其他参数无效,即该URI无效。
                                      port:URI中的端口号,比如80,当且仅当URI中指定了scheme和host参数,port才有效。
                                      path:则表示Uri中所代表资源的完整路径。
     5、Type属性

            用于指定该Data所指定Uri对应的MIME类型,比如 image/png、 message/rfc822等。

    Data属性通常与Type一起使用但关系比较微妙,在Java文件中为Intent设置Data属性与Type属性时,有以下三种情况:
            1、如果为Intent先设置Data属性,后设置Type属性,则Type属性会将Data属性覆盖。
            2、如果为Intent先设置Type属性,后设置Data属性,则Data属性会将Type属性覆盖。
            3、如果希望Intent同时有Type属性和Data属性,则需要调用Intent的setDataAndType()方法。

    从源码中就可以看出为什么会覆盖。
         public Intent setData(Uri data) {
            mData = data; //设置data
            mType = null; //将Type置为null
            return this;
        }

        在AndroidManifest文件中为组件声明Data和Type属性都通过<data .../>
                 <data 
                        android:mimeType=""      //用于声明该组件所能匹配的Intent的Type属性
                        android:scheme=""           // 用于声明该组件所能匹配的Intent的Data属性的scheme部分
                        android:host=""                 // 用于声明该组件所能匹配的Intent的Data属性的host部分
                        android:port=""                 // 用于声明该组件所能匹配的Intent的Data属性的port部分
                        android: path=""                // 用于声明该组件所能匹配的Intent的Data属性的path部分
                        android:pathPrefix=""      // 用于声明该组件所能匹配的Intent的Data属性的path部分前缀部分
                        android:pathPattern=""   // 用于声明该组件所能匹配的Intent的Data属性的path的字符串模板
                    />
     6、Extra属性
        
                该属性通常用于在多个Activity之间进行数据传递。
                调用Intent.putExtra()方法可以传入一个Bundle对象, Bundle对象就像一个Map一样可以传入多组key-value,当然也可以不传Bundle,直接调用 putExtra(String name, String value)方法传一组key-value来传递数据。

   7、Flag属性

            该属性用于为Intent添加额外的控制旗标。



Intent寻找组件的方式:
    
    1、显式Intent:
            使用这种方式启动组件的前提是我们明确知道要启动哪一个组件,即知道组件的包名与组件名。
            在此前提下,有三种方式设置所要启动的组件:
                    1、在创建Intent实例时为将目标组件作为Intent构造函数的参数传递给Intent。
                    2、调用Intent的setClass()方法或setClassName()方法,为Intent设置目标组件。
                    3、创建 componentName对象,为intent设置component属性。
    2、隐式Intent:
            没有指定Component属性,即使用Intent启动组件前,并不明确它到底要启动哪一个组件。这时虽然不明确具体要启动哪一个组件,但可以为Intent设置action、category、data等过滤条件,以此来筛选出要启动哪一个组价。
        
    打个比方来说明这两种方式,把使用Intent来启动组件比作男生找女朋友。显式Intent就好比这个男生明确知道自己喜欢谁,所以他就会直接找那个女生表白,那个女生就相当于Android中的Component属性。而隐式Intent就比如那个男生并不确定自己喜欢谁,所以他找女朋友时,就会自己找女朋友的要求来找那个女生,而他的要求就比如女生要高、白、身材瘦一点等等。这些条件就相当于Android中的Action、category等。



IntentFilter匹配组件
    
        在这里再说一下 IntentFilter,Intent Filter 描述了一个组件愿意接收什么样的 Intent 对象,Android 将其抽象为android.content.IntentFilter 类。在 Android 的 AndroidManifest.xml 配置文件中可以通过 <intent-filter >节点为一个 Activity 指定其 Intent Filter,以便告诉系统该 Activity 可以响应什么类型的 Intent。
    当程序员使用 startActivity(intent) 来启动另外一个 Activity 时,如果直接指定 intent 了对象的 Component 属性,那么 Activity Manager 将试图启动其 Component 属性指定的 Activity。否则 Android 将通过 Intent 的其它属性从安装在系统中的所有 Activity 中查找与之最匹配的一个启动,如果没有找到合适的 Activity,应用程序会得到一个系统抛出的异常。这个匹配的过程如下:

   

        一个组件中可以有多个intent-filter,一个Intent只要能够匹配任何一组 intent-filter即可成功启动对应的Activity。
    
         Action的匹配规则:
            
                1、 intent中的Action必须能够和intent-filter中的action匹配,这里指的匹配是两个action字符串必须完全一致。这里要注意一点一个intent-filter钟可能包含多个action,那么intent中的Action只要能够和intent-filter中的一个action相匹配即可匹配成功
                2、action区分大小写,大小写不同字符串相同则不能够匹配成功。
                3、一个Intent中只能包含一个Action,如果先后设置了两个Action,则后面的Action会覆盖前面的Action。
                4、使用隐式Intent启动组件时,Intent中必须包含一个Action。

         category的匹配规则:
                
                1、category在匹配的时候和action一样字符串完全一致。
                2、区分大小写
                3、一个Intent中可以包含多个category,但Intent中的category必须和 intent-filter的category都能够匹配成功才行。当然Intent中可以不必包含intent-filter中的所有category。
                4、一个Intent中可以不包含category。但如果没有设置category,在启动组件时,会给Intent中默认添加一个 android.intent.category.DEFAULT的category,这也就是在AndroidManifest文件中为组件设置intent-filter时必须要有一个category标签,其值为android.intent.category.DEFAULT。















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值