Intent

  Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景。

/framework/base/core/java/android/content/Intent.java
public class Intent implements Parcelable, Cloneable {

}

Intent的常见用法

启动Activity

1 . Context.startActivity(Intent intent);
2 . Context.startActivityForResult();

发送Broadcast

1 . Context.sendBroadcast();
2 . Context.sendOrderedBroadcast();
3 . Context.sendStickyBroadcast();

启动Service

1 . Context.startService();
2 . Context.bindService();

Intent种类

  Intent大致可以分为两种:显示Intent和隐式Intent;

显示Intent

  通过提供目标应用的软件包名称或完全限定的组件类名来指定处理Intent的应用。
  就是可以直接指定需要打开的Activity对应的类;
1 . 构造方法传入Class,是最常用的方式:

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

2 . 通过setClass()方法:

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

3 . 通过setClassName()方法:

Intent intent = new Intent();
intent.setClassName(this,"com.example.kang.ui.SecondActivity");
startActivity(intent);

Intent intent = new Intent();
intent.setClassName("com.example.kang","com.example.kang.ui.SecondActivity");
startActivity(intent);

  以上四个方法:Intent(Context packageContext, Class<?> cls)、setClass(@NonNull Context packageContext, @NonNull Class<?> cls)、setClassName(@NonNull Context packageContext, @NonNull String className)、setClassName(@NonNull String packageName, @NonNull String className),最终都是使用的ComponentName的不同构造方法去初始化两个String类型的变量mPackage和mClass。

  显示Intent通过Component可以直接设置需要调用的Activity类,可以唯一确定一个Activity,意图特别明确,所以称之为显示的。设置这个类的方式可以是Class对象(如SecondActivity.class),也可以是包名加类名的字符串(如"com.example.kang.ui.SecondActivity")。

隐式Intent

  隐式Intent不明确指定启动哪个Activity,而是设置Action、Data、Category,让系统来筛选出合适的Activity。筛选是根据AndroidManifest.xml文件中所有的来筛选的。

  下面以Action为例:
  AndroidManifest.xml文件中,首先被调用的Activity要有一个带有并且包含的Activity,设定它能处理的Intent,并且category设置为"android.intent.category.DEFAULT"。action的name是一个字符串,可以自定义,比如这里定义为"com.example.kang.hiden",如下:

<activity android:name=".activities.HiddenIntentActivity">
    <intent-filter>
        <action android:name="com.example.kang.hiden" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

  然后,我们就可以通过设置的这个action来找到上面的这个HiddenIntentActivity。下面是两种方式在代码中来设置Action,效果都是一样的。

//通过setAction()方法来设置;
Intent intent = new Intent();
intent.setAction("com.example.kang.hiden");
startActivity(intent);

//通过构造方法来设置;
Intent intent = new Intent("com.example.kang.hiden");
startActivity(intent);

Intent的属性

  Intent对象常见的包括七种属性:Action(动作)、Data(数据)、Category(类别)、Type(数据类型)、Component(组件)、Extra(扩展信息)、Flag(标志位)。其中,最常用的是Action和Data。

Action:操作

  是一个字符串变量,可以用来指定Intent要执行的动作类别。

Data:数据

  引用待操作数据和/或该数据 MIME 类型的 URI(Uri 对象)。提供的数据类型通常由 Intent 的操作决定。例如,如果操作是 ACTION_EDIT,则数据应包含待编辑文档的 URI。
  要仅设置数据 URI,请调用 setData()。要仅设置 MIME 类型,请调用 setType()。如有必要,您可以使用 setDataAndType() 同时显式设置二者。
  若要同时设置 URI 和 MIME 类型,请勿调用 setData() 和 setType(),因为它们会互相抵消彼此的值。请始终使用 setDataAndType() 同时设置 URI 和 MIME 类型。
  一个URI对象是一个引用的data的表现形式,或是data的MIME类型;data的类型由Intent的action决定。

Category:用来表现动作的类别

一个包含Intent额外信息的字符串,表示哪种类型的组件来处理这个Intent。任何数量的Category 描述都可以添加到Intent中,但是很多intent不需要category。

Type:指定数据类型

  一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。

Compoment name:组件名称

  要启动的组件名称。
  这是可选项,也是构建显示Intent的一项重要信息,这意味着Intent应该仅仅传递给由组件名称定义的应用组件。如果没有组件名称,则 Intent则为隐式,且系统将根据其他Intent信息决定哪个组件应当接收Intent。如需在应用中启动特定的组件,则应指定该组件的名称。
I  ntent 的这一字段是 ComponentName 对象,您可以使用目标组件的完全限定类名指定此对象,其中包括应用的软件包名称。例如,com.example.ExampleActivity。您可以使用 setComponent()、setClass()、setClassName(),或 Intent 构造函数设置组件名称。
  指定Intent的目标组件名称,当指定了这个属性后,系统将跳过匹配其他属性,而直接匹配这个属性来启动对应的组件。

Extra:扩展信息

  携带完成请求操作所需的附加信息的键值对。
  Intent可以携带的额外 key-value 数据,你可以通过调用putExtra()方法设置数据,每一个 key对应一个 value数据。你也可以通过创建 Bundle对象来存储所有数据,然后通过调用putExtras()方法来设置数据。

Flag:期望这个意图的运行模式

用来指示系统如何启动一个Activity,可以通过setFlags()或者addFlags()可以把标签flag用在Intent中。

类型 作用
FLAG_ACTIVITY_CLEAR_TOP 相当于SingleTask
FLAG_ACTIVITY_SINGLE_TOP 相当于SingleTop
FLAG_ACTIVITY_NEW_TASK 相当于SingleInstance
FLAG_ACTIVITY_NO_HISTORY 当离开该Activity后,该Activity将被从任务栈中移除

Bundle

  Bundle是一个类型安全的容器,它的实现是基于HashMap的一种封装,但是这两者之间存在很大的差别。HashMap可以存储任何的键值对,值可以是任何的Java类型,但是对Bundle而言,它的值只能是基本数据类型或基本类型的数组。

PendingIntent

Intent解析

Intent匹配

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-----------------last line for now----------------