当前位置: 首页 > 知识库问答 >
问题:

不推荐使用OnActivityResult方法,替代方案是什么?

史高阳
2023-03-14

我最近发现onActivityResult是不推荐的。我们该怎么处理?

有什么替代方案吗?

共有1个答案

淳于博
2023-03-14

developer.android.com提供了基本培训。

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

老办法:

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

由于可以将回调函数与意图一起设置,因此可以将其用于任何活动。

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

 类似资料:
  • 问题内容: 现在我正在使用类似 我需要您的意见以最好/最有效的方式对密码进行加密,当然,加密的密码应受PHP 7.xx支持,并且也应可解密,因为我的客户确实希望选择“恢复”密码而不生成新密码一。 问题答案: 最佳做法是对密码进行哈希处理,以使密码不可解密。这使可能已获得对数据库或文件的访问权限的攻击者的处境变得更加困难。 如果必须加密数据并使其可解密,请访问https://paragonie.co

  • 我现在使用下面的代码来断言 ,这会给你糟糕的失败消息,比如“java.lang.断言错误” 收到评论/答案后编辑 我最初的担心是因为Eclipse将以下导入语句显示为已弃用 在查看Hamcrest API文档时,有3个重载的方法变体,其中只有一个被弃用。 因此,为了澄清来自@mark的评论和来自@matt的回答,我在上面发布的的使用是有效的,而不是不建议使用的。

  • [1]http://springfox.github.io/springfox/javadoc/2.7.0/springfox/documentation/swagger/web/classorapiannotationresourcegrouping.html [2]https://github.com/springfox/springfox/issues/1307

  • 最近,我从使用RESTEasy 2.3.6.final更新到了最新的版本,结果发现org.jboss.RESTEasy.spi.NotFoundException和org.jboss.RESTEasy.spi.unauthorizedException是不推荐的。这些有替代品吗?

  • 背景:在声纳Qube中,存在一个自定义的质量门,称为say。这不是默认的质量门。在Jenkins中,我使用参数为一组API配置了这个SonarQube质量门,并且运行良好。 我更喜欢这样一个解决方案,我可以配置一些詹金斯,因为我可以访问詹金斯,但不是声纳Qube配置。

  • 问题内容: 我有一个正在使用的旧代码。 这里是我的代码,其中和已经导入。 在这里,我有些疑问,我编写的代码可以正常工作,但是由于现在不推荐使用,所以我想删除它。我浏览了许多文档,发现使用门户或引用代替了此。我的理解是,如果我使用ref,那么变量get bind到该变量也可以访问DOM元素,但是我想我错了,因为它以这种方式工作。有人可以纠正我对此的理解 问题答案: 根据 此github问题 和 Re