OnActivityResult 方法已弃用,有什么替代方法? [英] OnActivityResult method is deprecated, what is the alternative?

查看:140
本文介绍了OnActivityResult 方法已弃用,有什么替代方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发现 onActivityResult 已被弃用.我们应该怎么做?

I recently discovered that onActivityResult is deprecated. What should we do to handle it?

为此引入了任何替代方案吗?

Any alternative introduced for that?

推荐答案

基本培训可在 developer.android.com.

这是一个关于如何将现有代码转换为新代码的示例:

Here is an example on how to convert the existing code with the new one:

老方法:

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();
    }
}

新方法(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);
}

新方法(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. A better approach would be to make it more generalised so that we can reuse it. The snippet below is used in one of my projects but beware that it's not well-tested and may not cover all the cases.

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);
    }
}

使用上述方法,您仍然需要在启动 Activity 或 Fragment 附件之前或期间对其进行注册.一旦定义,它就可以在活动或片段中重复使用.例如,如果你需要在大部分活动中开始新的活动,你可以像这样定义一个BaseActivity并注册一个新的BetterActivityResult:

With the above approach, you still have to register it before or during launching the activity or fragment attachment. Once defined, it can be reused within the activity or fragment. For example, if you need to start new activities in most of the activity, you can define a BaseActivity and register a new BetterActivityResult like this:

BaseActivity.java

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

之后,您可以简单地从任何子活动中启动一个活动,如下所示:

After that, you can simply launch an activity from any child activities like 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 一起设置,因此您可以将其重用于任何活动.

Since you can set the callback function along with the Intent, you can reuse it for any activities.

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

Similarly, you can also use other activity contracts using the other two constructors.

这篇关于OnActivityResult 方法已弃用,有什么替代方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆