【Android开发】 startActivityForResult() 被弃用问题

startActivityForResult() 被弃用问题

之前说过启动另一个 activity 可以通过用 Activity 类提供的 startActivityForResult()onActivityResult()API 来获取另一个 activity 返回的结果,但是现在我们现在会发现使用这样的 API 产生了错误提示。

'startActivityForResult(Intent!, Int): Unit' is deprecated

    /**
     * Call {@link Activity#startActivityForResult(Intent, int, Bundle)} from the fragment's
     * containing Activity.
     *
     * @param intent The intent to start.
     * @param requestCode The request code to be returned in
     * {@link Fragment#onActivityResult(int, int, Intent)} when the activity exits. Must be
     *                    between 0 and 65535 to be considered valid. If given requestCode is
     *                    greater than 65535, an IllegalArgumentException would be thrown.
     * @param options Additional options for how the Activity should be started. See
     * {@link Context#startActivity(Intent, Bundle)} for more details. This value may be null.
     *
     * @deprecated use
     * {@link #registerForActivityResult(ActivityResultContract, ActivityResultCallback)}
     * passing in a {@link StartActivityForResult} object for the {@link ActivityResultContract}.
     */
    @SuppressWarnings("DeprecatedIsStillUsed")
    @Deprecated
    public void startActivityForResult(@SuppressLint("UnknownNullness") Intent intent,
            int requestCode, @Nullable Bundle options) {
        if (mHost == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
        }
        getParentFragmentManager().launchStartActivityForResult(this /*fragment*/, intent,
                requestCode, options);
    }
    /**
     * Receive the result from a previous call to
     * {@link #startActivityForResult(Intent, int)}.  This follows the
     * related Activity API as described there in
     * {@link Activity#onActivityResult(int, int, Intent)}.
     *
     * @param requestCode The integer request code originally supplied to
     *                    startActivityForResult(), allowing you to identify who this
     *                    result came from.
     * @param resultCode The integer result code returned by the child activity
     *                   through its setResult().
     * @param data An Intent, which can return result data to the caller
     *               (various data can be attached to Intent "extras").
     *
     * @deprecated use
     * {@link #registerForActivityResult(ActivityResultContract, ActivityResultCallback)}
     * with the appropriate {@link ActivityResultContract} and handling the result in the
     * {@link ActivityResultCallback#onActivityResult(Object) callback}.
     */
    @SuppressWarnings("DeprecatedIsStillUsed")
    @Deprecated
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
            Log.v(FragmentManager.TAG, "Fragment " + this + " received the following in "
                    + "onActivityResult(): requestCode: " + requestCode + " resultCode: "
                    + resultCode + " data: " + data);
        }
    }

不管是 startActivityForResult() 还是 onActivityResult() 都被官方启用了,并且也提供了相应的解决策略,使用 registerForActivityResult() API。

public abstract ActivityResultLauncher<I> registerForActivityResult (ActivityResultContract<I, O> contract, 
                ActivityResultCallback<O> callback)
参数:
  • ActivityResultContract:定义生成结果所需的输入类型以及结果的输出类型。
  • ActivityResultCallback:是单一方法接口,带有 onActivityResult() 方法,可接受 ActivityResultContract 中定义的输出类型的对象。
返回:
  • ActivityResultLauncher: 可用于启动活动或处理准备好的调用的启动器。
val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

如果您有多个使用不同协定或需要单独回调的 activity 结果调用,则可以多次调用 registerForActivityResult(),以注册多个 ActivityResultLauncher 实例。每次创建 fragmentactivity 时,都必须按照相同的顺序调用 registerForActivityResult(),才能确保将生成的结果传递给正确的回调。

虽然 registerForActivityResult() 会注册您的回调,但它不会启动另一个 activity 并发出结果请求。这些操作由返回的 ActivityResultLauncher 实例负责。

ActivityResultLauncher 提供了四个公有的方法

类型方法描述
abstract ActivityResultContract<I, ?>getContract()Get the {@link ActivityResultContract} that was used to create this launcher.
abstract voidunregister()Unregisters this launcher, releasing the underlying result callback, and any references captured within it.
abstract voidlaunch(I input, ActivityOptionsCompat options)Executes an {@link ActivityResultContract}.
voidlaunch(I input)Executes an {@link ActivityResultContract}.

如果存在输入内容,启动器会接受与 ActivityResultContract 的类型匹配的输入内容。调用 launch() 会启动生成结果的过程。当用户完成后续 activity 并返回时,系统将执行 ActivityResultCallback 中的 onActivityResult().

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    val selectButton = findViewById<Button>(R.id.select_button)

    selectButton.setOnClickListener {
        // Pass in the mime type you'd like to allow the user to select
        // as the input
        getContent.launch("image/*")
    }
}

注意:registerForActivityResult() 必须要写在 fragment 和 activity 创建成功之前,但在 fragment 或 activity 的 Lifecycle 变为 CREATED 状态之前,您无法启动 ActivityResultLauncher。


android开发者指南:https://developer.android.google.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hovf-1120

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

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

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

打赏作者

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

抵扣说明:

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

余额充值