Activity - 1 启动

Intent

Android基本的设计理念是鼓励减少组件间的耦合,因此Android提供了Intent (意图),Intent提供了一种通用的消息系统,它允许在你的应用程序与其它的应用程序间传递Intent来执行动作和产生事件。使用Intent可以激活Android应用的三个核心组件:活动、服务和广播接收器。还可以通过intent.putExtra()等方法携带数据。
Intent 的用法大致可以分为两种,显式 Intent 和隐式 Intent,我们先来看一下显式 Intent 如何使用。

显式 Intent

一般是在相同的应用程序内部实现的。Intent 有多个构造函数的重载,其中一个是Intent(Context packageContext, Class<?> cls)。 这个构造函数接收两个参数,第一个参数 Context 要求提供一个启动活动的上下文,第二个 参数 Class 则是指定想要启动的目标活动,通过这个构造函数就可以构建出 Intent 的“意图”。 然后我们应该怎么使用这个 Intent 呢?Activity 类中提供了一个 startActivity()方法,这个方法 是专门用于启动活动的,它接收一个 Intent 参数,这里我们将构建好的 Intent 传入 startActivity()方法就可以启动目标活动了。

Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);

隐式 Intent

相比于显式 Intent,隐式 Intent 则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的 action ,category和data 等信息,然后交由系统去分析这个 Intent, 并帮我们找出合适的活动去启动。我们在编写需要被隐式调用的界面的清单文件时,会指定一个Intent Filter(意图过滤器),它是用来匹配隐式Intent的,当一个意图对象被一个意图过滤器进行匹配测试时,会有三个方面会被参考到:

  • 动作(action)
  • 数据(data)
  • 类别(catagory)
Intent intent = new Intent();  
intent.setAction("android.intent.action.CALL");  
intent.setData("Uri.parse("tel:") + mobile");//mobile为电话号码(是数字)   
startActivity(intent);  


<Intent-filter>
    <action android:name="android.intent.action.CALL"/>
    <category android:name"android.intent.category.DEFAULT"/>   
    <data android:scheme="tel"/>   
</Intent-filter>  

其中action的name随便设,category的name也可以随便设,不过android.intent.category.DEFAULT是调用startActivity时内部自动生成的(因此,想要接收隐式意图的活动必须在它们的意图过滤器中包含”android.intent.category.DEFAULT”)。

在意图过滤器中可以有多个动作和类别,但意图只能定义一个动作,所以只要定义的这个动作(action)和意图过滤器中的任意一个匹配就可以成功。类别(category)也是,只要匹配其中一个就行,不必匹配所有。但是,如果定义的类别在意图过滤器中找不到,就会报错,也就是说意图中定义的动作和意图在过滤器中必须有。并且当执行startActivity或者startActivityForResult时会给Intent默认带上default的categroy,所以要想匹配在IntentFilter中必须加上default的category。

data语法比较复杂,由两部分组成 URI和mimeType。mimeType指媒体类型,比如image/jpg

<data android:scheme="string"
    android:host="string"
    android:port="80"
    android:path="/string"
    android:pathPattern="string"
    android:pathPrefix="/string"
    android:mimeType="string"/>

若data的过滤规则只指定了mimeType,也会默认生成URI的过滤规则,URI的默认值为content和file。
另外如果要为Intent指定完整的data(当指定了mimeType),必须要调用setDataAndType方法,不能先调用setData再调用setType,因为这两个方法会清除对方的值。
intent.setDataAndType(Uri.parse(“file://abc”, “image/png”)

当一个intent对象中的URI被用来和一个过滤器中的URI比较时,比较的是URI的各个组成部分。例如,如果过滤器仅指定了一个scheme,所有该scheme的URIs都能够和这个过滤器相匹配;如果过滤器指定了一个scheme、主机名但没有路经部分,所有具有相同scheme和主机名的URIs都可以和这个过滤器相匹配,而不管它们的路经;如果过滤器指定了一个scheme、主机名和路经,只有具有相同scheme、主机名和路经的URIs才可以和这个过滤器相匹配。当然,一个过滤器中的路径规格可以包含通配符,这样只需要部分匹配即可。

当使用隐式Intent打开activity时可以先判断一下该intent有没有匹配出对应intent。可以采用PackageManager的resolveActivity或者queryIntentActivities方法。方法如下。第二个参数要使用MATCH_DEFAULT_ONLY,这个标记的含义是仅仅匹配出在intent-filter中定义了的Activity。
getPackageManager().queryIntentActivities(intent,PackageManager.MATCH_DEFAULT_ONLY);
getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);

隐式 Intent 和 显式 Intent区别

显式意图一般在应用的内部使用,因为,在应用内部已经知道了组件的名称,直接激活就行了。
当一个应用要激活另一个应用中的Activity时(看不到源代码),只能使用隐式意图,根据Activity配置的意图过滤器建一个意图,让意图中的各项参数的值都跟过滤器匹配,这样就可以激活其他应用中的Activity。所以,隐式意图是在应用与应用之间使用的。(如果自己开发的应用,希望其中的某个Activity能让其他应用访问到,就为这个Activity定义一个意图过滤器,则,其他应用就可以根据意图过滤器中的参数设置意图对象,然后传给操作系统,操作系统就可以找到和这个意图匹配的过滤器,找到过滤器后就可以激活意图所在的Activity)。

显式意图有点是效率高,系统直接精确定位要启用的组件,但耦合度也高,如果通过这种方式调用一些系统组件的话,容易因为版本更新,类名、包名、包结构变化等原因导致程序崩溃。
而隐式意图能够降低程序的耦合度,但由于每次意图执行的时候,系统都会搜索所有可用的intentfilter,来查看是否有匹配的内容,所以效率更低。所以具体的使用还要看具体的情况。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值