为图书馆项目中的结果请求代码启动 Activity

Start Activity for Result Request Code in Library Project

我目前正在为 Android 开发一个图书馆项目,我计划将其开源。该库有一个 activity,我需要 return 结果,因此使用该库的应用程序需要调用 startActivityForResult

我的问题是,如果用户在他们的应用程序中有一个 activity,它会在他们自己的应用程序中调用第二个 activity,这也需要 return 结果,而这activity 需要从我的库中调用 activity,我的库 activity 和它们自己的 activity 将使用相同的 onActivityResult 回调。有没有办法避免我的活动请求代码,而不是与他们自己的请求代码之一冲突,这只是假设他们自己的请求代码是 1、2、3 等并且我启动我的库 activity 请求的情况来自任意数字的代码,例如 1000。

这是它的工作方式还是有更好的方法来避免我的图书馆请求代码与另一个应用程序活动请求代码冲突?

我认为库应该提供一个参数来指定开发人员自己为 startActivityForResult 请求代码,这样它们就不会在相同的 activity 或调用它们的片段中发生冲突。

ActivityA可以选择自己的请求码,ActivityB永远不知道A用的是哪个请求码

这没问题,因为请求代码是纯本地的。每个 Activity 实例都与其他 Activity 实例分开 - 它们不会混淆,因为它们都实现相同的方法(如 onCreate() 或你的情况 onActivityResult() ) .

让我们看一下 source code for android.app.Activity 中的一些行,从第 4614 行开始

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            // If this start is requesting a result, we can avoid making
            // the activity visible until the result is received.  Setting
            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
            // activity hidden during this time, to avoid flickering.
            // This can only be done when a result is requested because
            // that guarantees we will get information back when the
            // activity is finished, no matter what happens to it.
            mStartedActivity = true;
        }
        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            // Note we want to go through this method for compatibility with
            // existing applications that may have overridden it.
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

引用代码段中的注释表明,请求码是用来判断是否有结果返回的

请注意,startActivityForResult(Intent intent, int requestCode, Bundle options) 的参数从 Instrumentation class 中的同一包 [=51] 传递到方法 execStartActivity() =]

但是 execStartActivity() 还有四个其他参数用于识别调用应用程序和当前 Activity 实例(我不会在这里详细介绍 Binder 框架,但是有例如关于这个主题的 a youtube video):

Context who, IBinder contextThread, IBinder token, Activity target

再次说明,请求码只是用来判断是否有结果返回(对于否定的请求码,startActivityForResult()startActivity()一样处理)

return requestCode >= 0 ? am.getResult() : null;

除此之外,请求代码只是传递回调用 startActivityForResult()Activity

因此,如果 Activity 不对不同类型的请求使用相同的请求代码,一切都很好。