我最近发现onActivityResult已弃用。我们该怎么处理呢?

有什么替代方案吗?


当前回答

dor506回答为我工作,因为我在我的大多数项目中使用BaseActivity,所以对我来说更容易在单个文件中更改代码,而不是我所有的活动。我已经写了这个代码的java版本。

BaseActivity代码:

private int requestCode = -1;
private ActivityResultLauncher<Intent> resultHandler = null;

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mContext = this;

    registerForActivityResult();
}
  private final void registerForActivityResult() {
    if (shouldRegisterForActivityResult()) {
        this.resultHandler = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
                new ActivityResultCallback() {

            public void onActivityResult(Object var1) {
                this.onActivityResult((ActivityResult)var1);
            }

            public final void onActivityResult(ActivityResult result) {
                Intrinsics.checkNotNullExpressionValue(result, "result");
                AppActivityClass.onActivityResult(result.getData(), AppActivityClass.this.requestCode, result.getResultCode());
                AppActivityClass.this.requestCode = -1;
            }
        });
    }
}

public final void startActivityForResult(int requestCode, Intent intent) {
    this.requestCode = requestCode;
    if (resultHandler != null) {
        resultHandler.launch(intent);
    }
}

protected static void onActivityResult(Intent intent, int requestCode, int resultCode) {
}

protected Boolean shouldRegisterForActivityResult() {
    return false;
}

现在在任何活动中使用这样的代码:

 @Override
protected Boolean shouldRegisterForActivityResult() {
    return true;  // this will override the baseactivity method and we can use onactivityresult
}

  private void someMethod(){
    Intent i = new Intent(mContext,SomeOtherClassActivity.class);
    startActivityForResult(101,i);
}

  @Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 101) {
        if (resultCode == RESULT_OK) {
            //revert from called class
        }
    }
}

其他回答

如果您正在使用SMS同意API,则使用以下代码(Kotlin):

resultLauncher.launch( consentIntent
                            )

    var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        // There are no request codes
    //    val data: Intent? = result.data
        val message = result.data?.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
        getOtpFromMessage(message)

    }
}

我使用kotlin扩展,使它非常简单。在你的扩展中添加以下扩展功能。kt文件:

fun AppCompatActivity.startForResult(intent: Intent,
    onResult: (resultCode: Int, data: Intent?) -> Unit
) {
    this.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {result ->
        onResult(result.resultCode, result.data)
    }.launch(intent)
}

现在,在继承AppCompatActivity的任何活动中,你可以使用下面的简单代码:

val i = Intent(this, TargetActivity::class.java)
startForResult(i) { resultCode, data ->
   //put your code here like:
   if (resultCode == RESULT_OK) {
      //your code here...
      }
   }
}

更新 上述实现可能导致以下异常: java.lang.IllegalStateException: LifecycleOwner xxxx正在尝试注册,而当前状态为恢复。生命周期所有者必须在启动之前调用寄存器。

因此,registerForActivityResult应该提前调用,例如在onCreate之前。这是另一种解决方案。

在你的扩展中添加以下扩展功能。kt文件:

fun AppCompatActivity.registerForResult(onResult: (resultCode: Int, data: Intent?) -> Unit):
        ActivityResultLauncher<Intent> {
    return this.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        onResult(result.resultCode, result.data)
    }
}

现在,在继承AppCompatActivity的任何活动中,你可以使用下面的简单代码:

为每个需要结果的操作定义一个类成员变量

private val myActionResult = registerForResult { resultCode, data ->
   //put your code here like:
   if (resultCode == RESULT_OK) {
      //your code here...
      }
   }
}

启动动作

val i = Intent(this, TargetActivity::class.java)
myActionResult.launch(i)

分享我找到的解决方法

首先,使用registerForActivityResult为结果注册这个活动 这将返回一个类型为ActivityResultLauncher<Intent!> 像这样,

private val getResult =
        registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) {
            if (it.resultCode == Activity.RESULT_OK) {
                val value = it.data?.getStringExtra("input")
            }
        }

现在,无论我们想在哪里启动result活动我们都可以使用getresult。launch(intent)

一个简单的例子:registerForActivityResult和requestmultiplepermission from Activity和Fragment

请求活动以获得活动的结果

registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { activityResult ->
    if (activityResult.resultCode == Activity.RESULT_OK) {
        //...
    }
}

检查ActivityResult

向活动请求许可?

registerForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
) {
    //it: Map<String, Boolean>
}

从片段?

使用相同的方法,但确保将这些实现放在初始化中,onAttach()或onCreate()

dor506回答为我工作,因为我在我的大多数项目中使用BaseActivity,所以对我来说更容易在单个文件中更改代码,而不是我所有的活动。我已经写了这个代码的java版本。

BaseActivity代码:

private int requestCode = -1;
private ActivityResultLauncher<Intent> resultHandler = null;

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mContext = this;

    registerForActivityResult();
}
  private final void registerForActivityResult() {
    if (shouldRegisterForActivityResult()) {
        this.resultHandler = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
                new ActivityResultCallback() {

            public void onActivityResult(Object var1) {
                this.onActivityResult((ActivityResult)var1);
            }

            public final void onActivityResult(ActivityResult result) {
                Intrinsics.checkNotNullExpressionValue(result, "result");
                AppActivityClass.onActivityResult(result.getData(), AppActivityClass.this.requestCode, result.getResultCode());
                AppActivityClass.this.requestCode = -1;
            }
        });
    }
}

public final void startActivityForResult(int requestCode, Intent intent) {
    this.requestCode = requestCode;
    if (resultHandler != null) {
        resultHandler.launch(intent);
    }
}

protected static void onActivityResult(Intent intent, int requestCode, int resultCode) {
}

protected Boolean shouldRegisterForActivityResult() {
    return false;
}

现在在任何活动中使用这样的代码:

 @Override
protected Boolean shouldRegisterForActivityResult() {
    return true;  // this will override the baseactivity method and we can use onactivityresult
}

  private void someMethod(){
    Intent i = new Intent(mContext,SomeOtherClassActivity.class);
    startActivityForResult(101,i);
}

  @Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 101) {
        if (resultCode == RESULT_OK) {
            //revert from called class
        }
    }
}