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

Intent启动活动

Intent启动活动主要分为两类:显示Intent 和 隐式Intent

显示Intent

  1. 使用这种方式来启动活动,Intent 的“意图”非常明显,因此我们称之为 显式 Intent 。示例代码如下:
  1. //创建Intent意图
  2. Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
  3. //调用Activity类中的方法启动Intent中指定的类
  4. startActivity(intent);

构建Intent的构造函数:

  1. /**
  2. * @param packageContext: A Context of the application package implementing this class.
  3. * @param cls: The component class that is to be used for the intent.
  4. */
  5. public Intent(Context packageContext, Class<?> cls) {
  6. mComponent = new ComponentName(packageContext, cls);
  7. }


隐示Intent_启动应用内活动

隐式 Intent 并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的 action 和 category 等信息,然后交由系统去分析这个 Intent,并找出可以响应我们这个隐式 Intent 的活动。
隐示Intent的实现步骤:

  1. 在AndroidManifest.xml 清单下配置需要隐示启动的Activity。即,在 标签中通过标签来指定这个活动能够响应的action和category。

    1. <activity android:name=".SecondActivity" >
    2. <intent-filter>
    3. <action android:name="com.example.activitytest.ACTION_START" />
    4. <category android:name="android.intent.category.DEFAULT" />
    5. </intent-filter>
    6. </activity>

    标签中我们指明了当前活动可以响应 com.example.activitytest.ACTION _START 这个 action,而 标签则包含了一些附加信息,更精确地指明了当前的活动能够响应的 Intent 中还可能带有的 category。只有 中的内容同时能够匹配上 Intent 中指定的 action 和 category 时,这个活动才能响应该 Intent。

  2. 在FirstActivity中隐示启动SecondActivity

    1. Intent intent = new Intent("com.example.activitytest.ACTION_START”);
    2. intent.addCategory("com.example.activitytest.MY_CATEGORY")
    3. startActivity(intent);

    这里使用了 Intent 的另一个构造函数,直接将 action 的字符串传了进去,表明我们想要启动能够响应 com.example.activitytest.ACTION _START 这个 action 的活动。而,android.intent.category.DEFAULT 是一种默认的 category,在调用 startActivity() 方法的时候会自动将这个 category 添加到 Intent 中。
    注意:
    每个 Intent 中只能指定一个 action,但却能指定多个 category。

隐示Intent_启动应用外活动

  1. 创建Intent时,指定响应其他应用的action

    1. Intent intent = new Intent(Intent.ACTION_VIEW);
    2. intent.setData(Uri.parse("http://www.baidu.com"));
    3. startActivity(intent)

    指定了 Intent 的 action 是 Intent.ACTION_VIEW,这是一个 Android 系统内置的动作,其常量值为 android.intent.action.VIEW 。然后通过 Uri.parse() 方法,将一个网址字符串解析成一个 Uri 对象,再调用 Intent 的 setData() 方法将这个 Uri 对象传递进去。这样就可以跳转到系统的浏览器访问该Uri地址,就这么简单。

  2. 我们还可以在 < intent-filter > 标签中再配置一个 标签,用于更精确地指定当前活动能够响应什么类型的数据。 标签中主要可以配置以下内容:

android:scheme:用于指定数据的协议部分,如: http 、geo (显示地理位置)、tel (拨打电话) 等。
android:host:用于指定数据的主机名部分,如上例中的 www.baidu 部分。
android:port:用于指定数据的端口部分,一般紧随在主机名之后。
android:path:用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
android:mimeType:用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

Intent传递数据


向下一个活动传递数据

Intent 中提供了一系列 putExtra() 方法的重载,把想要传递的数据暂存在 Intent 中,启动了另一个活动后,只需要把这些数据再从 Intent 中取出就可以了。以传递字符串为例:

  1. FirstActivity:

    1. Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    2. intent.putExtra("extra_data", "我是携带的字符串");
    3. startActivity(intent);
  2. SecondActivity:

    1. Intent intent = getIntent(); //通过getIntent()方法获取到用于启动当前活动的Intent,
    2. String data = intent.getStringExtra("extra_data”);
    3. system.out.print(data)

    通过getStringExtra() 方法来获取传递的数据。如果传递的是整型数据,则使用 getIntExtra() 方法;如果传递的是布尔型数据,则使用 getBooleanExtra() 方法,以此类推。

返回数据给上一个活动

Activity通过startActivityForResult() 方法来启动活动,这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。

  1. /* @param intent:The intent to start.
  2. @param requestCode:用于在之后的回调中判读数据来源 */
  3. public void startActivityForResult(@RequiresPermission Intent intent, int requestCode)
  1. FirstActivity:
    ```java //启动SecondActivity,并希望在SecondActivity销毁时返回一些数据给我 Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivityForResult(intent, 1);

//SecondActivity销毁时回调,并携带数据回来 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) {
case 1: if(resultCode == RESULT_OK) { String returnedData = data.getStringExtra(“data_return”); Log.d(“FirstActivity”, returnedData) } break; } }

  1. 2. SecondActivity:<br />
  2. ```java
  3. //当前活动销毁前执行,传递数据给上一个活动
  4. Intent intent = new Intent();
  5. intent.putExtra("data_return", "Hello FirstActivity”);
  6. setResult(RESULT_OK, intent); //第一个参数用于向上一个活动返回处理结果,一般只使用 RESULT_OK 或 RESULT_CANCELED 这两个值
  7. finish();

注意:
onActivityResult() 方法带有三个参数:
requestCode:即我们在启动活动时传入的请求码;
resultCode:即我们在返回数据时传入的处理结果;
data:即携带着返回数据的 Intent。
由于在一个活动中有可能调用 startActivityForResult() 方法去启动很多不同的活动,每一个活动返回的数据都会回调到 onActivityResult() 这个方法中,因此我们首先要做的就是通过检查 requestCode 的值来判断数据来源。

总结

  • Intent提供了多个重载的方法来“携带”额外的数据,如下所示:
  1. putExtras(Bundle data):向Intent中放入需要“携带”的数据包。
  2. Bundle getExtras():取出Intent中所“携带”的数据包。
  3. putExtra(String name,Xxx value):向Intent中按key-value对的形式存入数据。
  4. getXxxExtra(String name):从Intent中按key取出指定类型的数据。


  • Bundle就是一个简单的数据携带包,该Bundle对象包含了多个方法来入数据,如下所示:
  1. putXxx(String key,Xxx data):向Bundle中放入Int、Long等各种类型的数据。
  2. putSerializable(String key,Serializable data):向Bundle中放入一个可序列化的对象。

出Bundle数据携带包里的数据,Bundle提供了如下方法:

  1. getXxx(String key):从Bundle中取出Int、Long等各种类型的数据。
  2. getSerializable(String key,Serializable data):从Bundle中取出一个可序列化的对象。


  • Intent传递数据的底层原理

    其实Intent提供的putExtra(String name,Xxx value)、getXxxExtra(String name)方法,只是两个便捷的方法,这些方法依然是存取Intent所携带的Bundle中的数据。
    Intent的putExtra(String name,Xxx value)方法是“智能”的,当程序调用Intent的putExtra(String name,Xxx value)方法向Intent中存入数据时,如果该Intent中已经携带了Bundle对象,则该方法直接向Intent所携带的Bundle中存入数据;如果Intent还没有携带Bundle对象,putExtra(String name,Xxx value)方法会先为Intent创建一个Bundle,再向Bundle中存入数据。