对Intent这个基本的概念,一直觉得很简单有非常困惑,说简单,是因为使用的地方不多,并且使用案例很清晰,实际编程中不会有太多问题。说很困惑,是一直对这点理解感觉一团乱麻,不明白到底合适该声明intent-filter。这两天正好一个项目周期结束,我对android开发的探索也到了一个阶段,就决定把这个主题好好看一下。百度一下,发现一篇不错的文章:http://www.cnblogs.com/feisky/archive/2010/01/16/1649081.html,里面对基本的概念讲解还算清晰,但是毕竟是作者自己的笔记,有些杂乱,看完有些印象,还是有些困惑。今天早上在地铁上把官方文档看了一遍,http://developer.android.com/guide/components/intents-filters.html,终于搞明白是怎么一回事。
============================================================================
1. 为了保证应用的安全性,必须使用显式 Intent来启动Service,即使用类名方式启动。并且注意不要在Service中声明intent filters,这会引起潜在的安全性问题。
2. 构造显式Intent的时候,必须指定Component name,并且需要带有应用包名。可以通过setComponent(),setClass(), setClassName()方法设置component name,也可以通过Intent的构造方法。
3. 显式Intent与隐式Intent的区别,这点我一直感觉理解很模糊,看来官方的定义才明白怎么回事:
(1) Explicit Intent: specify the component to start by name(the fully-qualified class name). You'll typically use an explicit intent to start a component in your own app, because you know the class name of the activity or service you want to start.
(2) Implicit Intent: do not name a specific component, but instead declare a general action to perform, which allows a component from another app to handle it.
从上面的定义看,显式Intent指定了Intent的component name,而隐式Intent是指定了intent的action没有指定component name,这样就是说显示的intent不会去做intent resolution,会直接跳转到相应的组件。
4. 刚开始接触Android的时候就对manifest中的intent filter声明很感兴趣,看了官方文档找了一下精确的定义。
“An intent filter is an expression in an app's manifest file that specifies the type of intents that the component would like to receive.”,这个果然和intent的关系非常紧密,确切来说是与隐式intent的关系很密切。
5. 为了声明你的app可以接收哪些隐式Intent,可以在manifest文件中使用<intent-filter>标签为每一个组件声明一个或多个intent filters。每一个intent filter都根据intent的action/data/category指明了它可以接收的intent类型。操作系统只有再隐式Intent能通过其中一个intent filter的时候,才会把这个intent发送给app相应的组件。
Note: 这里有个需要注意的地方,显示Intent总是会直接被发送给相应的目标组件,不管该组件中intent filter是如何声明的,换句话说,intent filter是针对隐式Intent的。
6. 如果组件想要接收隐式Intent,则必须在组件的Intent filter中包含CATEGORY_DEFAULT 分类。 startActivity() 和 startActivityForResult()方法会认为所有的隐式Intent都声明了 CATEGORY_DEFAULT 分类。如果你没有在intent filter中声明这个category,那么系统不会把隐式intent解析到你的Activity的,即无法通过隐式Intent启动该Activity。
7. 讲解两个我一直觉得疑惑的action和category:
(1). ACTION_MAIN : 表明这个是应用的主入口(main entry point)并且不需要intent带有的任何data
(2). CATEGORY_LAUNCHER : 表明这个activity的icon应该被放在系统应用启动器上,用户可以从桌面启动这个activity。如果manifest中这个<activity>的标签中没有设置icon,系统会使用<application>标签中的icon作为启动图标。