我最近发现onActivityResult已经过时了.我们应该做些什么来处理它呢?

有没有其他办法?

Image showing code with onActivityResult striked out, indicating deprecation

推荐答案

developer.android.com美元提供基本培训.

下面是一个如何将现有代码转换为新代码的示例:

The old way:

public void openSomeActivityForResult() {
    Intent intent = new Intent(this, SomeActivity.class);
    startActivityForResult(intent, 123);
}

@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK && requestCode == 123) {
        doSomeOperations();
    }
}

The new way (Java):

// You can do the assignment inside onAttach or onCreate, i.e, before the activity is displayed
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    // There are no request codes
                    Intent data = result.getData();
                    doSomeOperations();
                }
            }
        });

public void openSomeActivityForResult() {
    Intent intent = new Intent(this, SomeActivity.class);
    someActivityResultLauncher.launch(intent);
}

The new way (Kotlin):

var resultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        // There are no request codes
        val data: Intent? = result.data
        doSomeOperations()
    }
}

fun openSomeActivityForResult() {
    val intent = Intent(this, SomeActivity::class.java)
    resultLauncher.launch(intent)
}

EDIT.更好的方法是使其更加通用,以便我们可以重用它.下面的代码片段用于我的一个项目中,但请注意,它没有经过良好测试,可能无法涵盖所有情况.

BetterActivityResult.java

import android.content.Intent;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCaller;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class BetterActivityResult<Input, Result> {
    /**
     * Register activity result using a {@link ActivityResultContract} and an in-place activity result callback like
     * the default approach. You can still customise callback using {@link #launch(Object, OnActivityResult)}.
     */
    @NonNull
    public static <Input, Result> BetterActivityResult<Input, Result> registerForActivityResult(
            @NonNull ActivityResultCaller caller,
            @NonNull ActivityResultContract<Input, Result> contract,
            @Nullable OnActivityResult<Result> onActivityResult) {
        return new BetterActivityResult<>(caller, contract, onActivityResult);
    }

    /**
     * Same as {@link #registerForActivityResult(ActivityResultCaller, ActivityResultContract, OnActivityResult)} except
     * the last argument is set to {@code null}.
     */
    @NonNull
    public static <Input, Result> BetterActivityResult<Input, Result> registerForActivityResult(
            @NonNull ActivityResultCaller caller,
            @NonNull ActivityResultContract<Input, Result> contract) {
        return registerForActivityResult(caller, contract, null);
    }

    /**
     * Specialised method for launching new activities.
     */
    @NonNull
    public static BetterActivityResult<Intent, ActivityResult> registerActivityForResult(
            @NonNull ActivityResultCaller caller) {
        return registerForActivityResult(caller, new ActivityResultContracts.StartActivityForResult());
    }

    /**
     * Callback interface
     */
    public interface OnActivityResult<O> {
        /**
         * Called after receiving a result from the target activity
         */
        void onActivityResult(O result);
    }

    private final ActivityResultLauncher<Input> launcher;
    @Nullable
    private OnActivityResult<Result> onActivityResult;

    private BetterActivityResult(@NonNull ActivityResultCaller caller,
                                 @NonNull ActivityResultContract<Input, Result> contract,
                                 @Nullable OnActivityResult<Result> onActivityResult) {
        this.onActivityResult = onActivityResult;
        this.launcher = caller.registerForActivityResult(contract, this::callOnActivityResult);
    }

    public void setOnActivityResult(@Nullable OnActivityResult<Result> onActivityResult) {
        this.onActivityResult = onActivityResult;
    }

    /**
     * Launch activity, same as {@link ActivityResultLauncher#launch(Object)} except that it allows a callback
     * executed after receiving a result from the target activity.
     */
    public void launch(Input input, @Nullable OnActivityResult<Result> onActivityResult) {
        if (onActivityResult != null) {
            this.onActivityResult = onActivityResult;
        }
        launcher.launch(input);
    }

    /**
     * Same as {@link #launch(Object, OnActivityResult)} with last parameter set to {@code null}.
     */
    public void launch(Input input) {
        launch(input, this.onActivityResult);
    }

    private void callOnActivityResult(Result result) {
        if (onActivityResult != null) onActivityResult.onActivityResult(result);
    }
}

使用上述方法,您仍然需要在启动活动或片段附件之前或期间注册它.一旦定义,它就可以在活动或片段中重用.例如,如果需要在大多数活动中启动新活动,可以定义BaseActivity并注册新的BetterActivityResult,如下所示:

BaseActivity.java

public class BaseActivity extends AppCompatActivity {
    protected final BetterActivityResult<Intent, ActivityResult> activityLauncher = BetterActivityResult.registerActivityForResult(this);
}

之后,您只需从以下任何子活动启动活动:

public void openSomeActivityForResult() {
    Intent intent = new Intent(this, SomeActivity.class);
    activityLauncher.launch(intent, result -> {
        if (result.getResultCode() == Activity.RESULT_OK) {
            // There are no request codes
            Intent data = result.getData();
            doSomeOperations();
        }
    })
}

由于您可以将回调函数与Intent一起设置,因此可以将其重用于任何活动.

同样,您也可以使用其他两个构造函数来使用其他活动契约.

Android相关问答推荐

带有kSP而不是kapt的Hilt

在Android Studio Iguana 2023.2.1中,哪里可以找到能量分析器?

房间@嵌入式VS一对一关系

react 本机生成失败,出现异常.错误:无法确定';<;宏/>;的类型

Jetpack Compose X.dp 性能问题?

如何使用react native下载android中/data/data/[应用程序包名称文件夹]/files中的文件

Android Drawable文件夹中的图像显示模糊

可从 Play store 下载链接访问未发布的应用

是什么导致调用 Firebase 服务器?

状态更改后 colored颜色 未正确更改

AttributionSource 需要 android.permission.BLUETOOTH_SCAN 权限的问题

Jetpack Compose TextField 在输入新字符时不更新

如何处理 com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: For input string: "T1V 4Y8" Kotlin

如何使用 ConstraintLayout 链接两个文本

Unity:Android 上随机接近零的 FPS 下降(提供了很多线索)

Android Material Date Range Picker - 如何仅更改所选范围日期的文本 colored颜色 ?

在 jetpack compose 中使用 .shadow 和 Button 会导致问题

不能在kotlin的lazycolumn中使用列表

在delphi中将Jnet_uri转换为Tbitmap

等到上一个事件完成 Rx