startActivityForResult() 被弃用问题
之前说过启动另一个 activity 可以通过用 Activity 类提供的 startActivityForResult() 和 onActivityResult() 的 API 来获取另一个 activity 返回的结果,但是现在我们现在会发现使用这样的 API 产生了错误提示。
'startActivityForResult(Intent!, Int): Unit' is deprecated
@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 , intent,
requestCode, options);
}
@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? ->
}
如果您有多个使用不同协定或需要单独回调的 activity 结果调用,则可以多次调用 registerForActivityResult(),以注册多个 ActivityResultLauncher 实例。每次创建 fragment 或 activity 时,都必须按照相同的顺序调用 registerForActivityResult(),才能确保将生成的结果传递给正确的回调。
虽然 registerForActivityResult() 会注册您的回调,但它不会启动另一个 activity 并发出结果请求。这些操作由返回的 ActivityResultLauncher 实例负责。
ActivityResultLauncher 提供了四个公有的方法
类型 | 方法 | 描述 |
---|
abstract ActivityResultContract<I, ?> | getContract() | Get the {@link ActivityResultContract} that was used to create this launcher. | abstract void | unregister() | Unregisters this launcher, releasing the underlying result callback, and any references captured within it. | abstract void | launch(I input, ActivityOptionsCompat options) | Executes an {@link ActivityResultContract}. | void | launch(I input) | Executes an {@link ActivityResultContract}. |
如果存在输入内容,启动器会接受与 ActivityResultContract 的类型匹配的输入内容。调用 launch() 会启动生成结果的过程。当用户完成后续 activity 并返回时,系统将执行 ActivityResultCallback 中的 onActivityResult().
val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
}
override fun onCreate(savedInstanceState: Bundle?) {
val selectButton = findViewById<Button>(R.id.select_button)
selectButton.setOnClickListener {
getContent.launch("image/*")
}
}
注意:registerForActivityResult() 必须要写在 fragment 和 activity 创建成功之前,但在 fragment 或 activity 的 Lifecycle 变为 CREATED 状态之前,您无法启动 ActivityResultLauncher。
android开发者指南:https://developer.android.google.cn
|