Intent 的使用

本文介绍了Android中Intent的基本概念,包括显式Intent和隐式Intent的使用方法,如何通过Intent在不同Activity间传递数据,以及如何返回数据给上一个Activity。还详细解释了使用ActivityResultAPI进行回调的过程。

Intent 的使用

显式 Intent

使用 Intent(Context packageContext, Class<?> cls) 构造函数创建 Intent 对象,第一个参数为上下文 Context,第二个参数指定想要启动的 Class。最后将 Intent 传入 startActivity() 方法中即可。

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

隐式 Intent

在清单文件 AndroidManifest.xml 中,通过在对应 <activity> 标签下配置 <intent-filter> 可以指定当前 Activity 能够响应的 action 和 category。

<activity
    android:name=".CurrentActivity"
    <intent-filter>
        <action android:name="ACTION_DIY" />
        <category android:name="CATEGORY_DIY" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

<action> 标签指定当前 Activity 可以响应 ACTION_DIY 这个 action,<category> 标签则指定可以响应 CATEGORY_DIY 这个 category。

Intent intent = new Intent("ACTION_DIY");
intent.addCategory("CATEGORY_DIY");
startActivity(intent);

android.intent.category.DEFAULT 是一种默认的 category,在调用 startActivity() 方法时会自动将这个 category 添加到 Intent 中 .
注意:在使用隐式 Intent 启动时清单文件下对应 <activity> 中必须存在该默认 category,否则会匹配失败然后报错。

隐式 Intent 的更多用法 —— 调用系统浏览器打开指定网页
先指定 Android 系统内置的 action Intent.ACTION_VIEW,其常量值为 android.intent.action.VIEW。然后通过 Uri.parse() 方法将一个网址字符串解析成一个 Uri 对象,并将其传入 Intent 的 setData() 方法中.

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(intent);

与此对应,<intent-filter> 下的 <data> 标签可以更精确地指定当前 Activity 能够响应的数据。<data> 标签下的主要配置内容如下:

  • android:scheme。用于指定数据的协议部分,如 http
  • android:host。用于指定数据的主机名部分,如 www.baidu.com
  • android:port。用于指定数据的端口部分,一般紧随在主机名之后。
  • android:path。用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
  • android:mineType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
<activity
    android:name=".CurrentActivity"
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" />
    </intent-filter>
</activity>

如上指定 <data android:scheme="http" />,就可以响应所有的 http 协议的 Intent。除了 http 协议外,还可以指定很多其他协议,如 geo 表示显示地理位置、tel 表示拨打电话。

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);

向下一个 Activity 传递数据

使用 Intent 提供的 putExtra() 方法可以把数据暂存到 Intent 中,调用 startActivity() 方法后即可将 Intent 中附带的数据传递给下一个 Activity。

// CurrentActivity.java
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
intent.putExtra("hello", "Hello!");
intent.putExtra("amie", "I am Amie.");
startActivity(intent);

目标 Activity 启动后使用 getIntent() 方法获取到用于启动它的 Intent 对象,这样就可以获取传递过来的数据了。使用 Intent 提供的 getExtras() 方法可以获取所有附带数据并返回一个 Bundle 对象,也可以使用 getStringExtra() 直接获取对应的字符串数据。此外 getIntExtra()getBooleanExtra() 等方法可以获取对应数据类型的数据。

// TargetActivity.java
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String extra = intent.getStringExtra("amie");

返回数据给上一个 Activity

startActivityForResult() 已经过时,推荐使用 Activity Result API 中的 registerForActivityResult(ActivityResultContract, ActivityResultCallback) 方法。

ActivityResultLauncher<I> registerForActivityResult(ActivityResultContract<I, O> contract, ActivityResultCallback<O> callback) 方法的官方文档:

Register a request to start an activity for result, designated by the given contract. This creates a record in the registry associated wit this caller, managing request code, as well as conversions to/from Intent under the hood. This must be called unconditionally, as part of initialization path, typically as a field initializer of an Activity or Fragment.
Params:
contract – the contract, specifying conversions to/from Intents
callback – the callback to be called on the main thread when activity result is available
Type parameters:
<I> – the type of the input(if any) required to call the activity
<O> – the type of output returned as an activity result
Returns:
the launcher that can be used to start the activity or dispose of the prepared call.

翻译:

通过指定的合约,注册一个用于启动 Activity 并获取返回结果的请求。这会在与该调用者关联的注册表中创建一条记录,管理请求码以及与 Intent 之间的转换。这必须作为初始化路径中的一部分,被无条件调用,通常作为 Activity 或 Fragment 的字段初始化器。
参数:
contract - 合约,指定与 Intent 之间的转换
callback - 当活动结果可用时在主线程上调用的回调
参数类型:
<I> – 调用 Activity 所需的输入类型(如果有)
<O> – 作为 Activity 返回结果的输出类型
返回:
可用于启动 Activity 或处理准备好的调用的启动器。

在 Activity Result API 中想要执行 Intent,需要将该 Intent 对象传入 ActivityResultLauncher 对象的 launch() 方法中。

注意:文档中强调这必须作为初始化路径中的一部分,也就是说 ActivityResultLauncher 必须在 Activity 的 onCreate() 方法或 Fragment 的 onCreate()onAttach() 方法调用前注册,然后在需要使用的地方调用其 launch() 方法。

public class CurrentActivity extends AppCompatActivity implements View.OnClickListener {

    // 在 onCreate() 方法前注册
    ActivityResultLauncher<Intent> launcher =
        registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
                new ActivityResultCallback<ActivityResult>() {
                    @Override
                    public void onActivityResult(ActivityResult result) {
                        if (result.getResultCode() == RESULT_OK) {
                            // TODO
                        }
                    }
                });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
    }

    @Override
    public void onClick(View v) {
        // ...
        Intent intent = new Intent(ContextActivity.this, TargetActivity.class);
        intent.putExtra("amie", "Hello! I am Amie.");
        launcher.launch(intent);
    }
}

在 TargetActivity 中,只需调用 setResult() 方法,并将处理结果码和带有数据的 Intent 传入其中,最后调用 finish() 方法即可销毁当前 Activity 并返回数据给上一个 Activity。

注意:当且仅当调用 finish() 方法后才可以回调成功,使用其他方式(如 startActivity() 启动等)回到上一个 Activity 都无法回调成功。

public class TargetActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
    }

    @Override
    public void onClick(View v) {
        // ...
        Intent intent = new Intent();
        intent.putExtra("vastness", "Hi! I am Vastness.");
        setResult(RESULT_OK, intent);
        finish();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿咩AmieVastness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值