1. Intent
Android基本的设计理念是鼓励减小组件间的耦合,所以Android提供了Intent (意图) ,
Intent提供了一种通用的消息系统,它容许在你的应用程序与其它的应用程序间传递 Intent 来执行动做和产生事件。
使用 Intent 能够激活 Android 应用的三个核心组件:活动(Activity)、服务(Service)和广播接收器(BroadcastReceiver)。android
2. 显式意图、隐式意图
Intent能够划分红显式意图和隐式意图。
显式意图:调用Intent.setComponent() 或 Intent.setClassName() 或 Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪一个组件。
如: 在 MainActicity 中打开一个新的 Acticity -- OtherActivity
1. Intent intent = new Intent();
2. intent.setComponent(new ComponentName(MainActivity.this, OtherActivity.class));
3. 第二行代码能够更换为:intent.setClass(MainActivity.this, OtherActivity.class);
4. 也能够使用构造器来指定组件: Intent intent = new Intent(MainActivity.this, OtherActivity.class)
三种 “显式意图” 指定方式等价
隐式意图:没有明确指定组件名的Intent为隐式意图。
Android系统会根据隐式意图中设置的动做(action)、类别(category)、数据(data: URI和数据类型)找到最合适的组件来处理这个意图
例如拨打电话的意图:
Uri uri = Uri.parse("tel:" + phoneCode);
Intent intent = new Intent(Intent.ACTION_CALL, uri);
对于隐式意图,Android是怎样寻找到这个最合适的组件呢?记的前面咱们在定义活动时,指定了一个intent-filter,Intent Filter(意图过滤器)其实就是用来匹配隐式Intent的,当一个意图对象被一个意图过滤器进行匹配测试时,只有三个方面会被参考到:动做、数据(URI以及数据类型)和类别。
动做测试(Action test)
一个意图对象只能指定一个动做名称,而一个过滤器可能列举多个动做名称。若是意图对象或过滤器没有指定任何动做,结果将以下:
+ 若是过滤器没有指定任何动做,那么将阻塞全部的意图,所以全部的意图都会测试失败。没有意图可以经过这个过滤器。
<intent-filter><!-- 空的 --></intent-filter>
+ 另外一方面,只要过滤器包含至少一个动做,一个没有指定动做的意图对象自动经过这个测试
类别测试(Category test)
对于一个可以经过类别匹配测试的意图,意图对象中的类别必须匹配过滤器中的类别。这个过滤器能够列举另外的类别,但它不能遗漏在这个意图中的任何类别。
原则上一个没有类别的意图对象应该总可以经过匹配测试,而无论过滤器里有什么。大部分状况下这个是对的。
但有一个例外,Android把全部传给startActivity()的隐式意图看成他们包含至少一个类别:"android.intent.category.DEFAULT" (CATEGORY_DEFAULT常量)。
所以自定义 Activity 的时候,不要觉得光定义一个 action 就够了。这样用 startActivity() 来激活这个 Activity 的时候将一直报错。
缘由就是,他内部要求去匹配 android.intent.category.DEFAULT 这个类别。
所以,想要接收隐式意图的活动必须在它们的意图过滤器中包含"android.intent.category.DEFAULT"。
(带"android.intent.action.MAIN"和"android.intent.category.LAUNCHER"设置的过滤器是例外)
数据测试(Data test)
当一个意图对象中的URI被用来和一个过滤器中的URI比较时,比较的是URI的各个组成部分。
例如,若是过滤器仅指定了一个scheme,全部该scheme的URIs都可以和这个过滤器相匹配;
若是过滤器指定了一个scheme、主机名但没有路经部分,全部具备相同scheme和主机名的URIs均可以和这个过滤器相匹配,而无论它们的路经;
若是过滤器指定了一个scheme、主机名和路经,只有具备相同scheme、主机名和路经的URIs才能够和这个过滤器相匹配。
固然,一个过滤器中的路径规格能够包含通配符,这样只须要部分匹配便可。
数据测试同时比较意图对象和过滤器中指定的URI和数据类型。规则以下:
a. 一个既不包含URI也不包含数据类型的意图对象仅在过滤器也一样没有指定任何URIs和数据类型的状况下才能经过测试。
b. 一个包含URI但没有数据类型的意图对象仅在它的URI和一个一样没有指定数据类型的过滤器里的URI匹配时才能经过测试。
这一般发生在相似于mailto:和tel:这样的URIs上:它们并不引用实际数据。
c. 一个包含数据类型但不包含URI的意图对象仅在这个过滤器列举了一样的数据类型并且也没有指定一个URI的状况下才能经过测试。
d. 一个同时包含URI和数据类型(或者可从URI推断出数据类型)的意图对象能够经过测试,若是它的类型和过滤器中列举的类型相匹配的话。
若是它的URI和这个过滤器中的一个URI相匹配或者它有一个内容content:或者文件file: URI并且这个过滤器没有指定一个URI,那么它也能经过测试。
换句话说,一个组件被假定为支持content:和file: 数据若是它的过滤器仅列举了一个数据类型。
3. 使用隐式意图
有两个意图的过滤器都匹配了某此请求,android 会出现一个列表菜单,供用户选择。测试