Boardy
Boardy

Reputation: 36237

Start Activity for Result Request Code in Library Project

I am currently working on a library project for Android which I plan on open sourcing. The library has an activity that I need to return a result for so the app that's utilising the library will need to call startActivityForResult.

My question is, if the user has an activity within their app, which calls a second activity within their own app which also needs to return a result, and this activity needs to call the activity from my library, my libraries activity, and their own activity will be using the same onActivityResult callback. Is there a way to avoid my activities request code, not conflicting with one of their own request codes, is it just a case of assume their own request codes are 1, 2, 3 etc and I start my libraries activity request code from some arbitrary number like 1000.

Is this just the way it works or is there a better way to avoid my request code for my library conflicting with another apps activities request code?

Upvotes: 1

Views: 1290

Answers (2)

Bö macht Blau
Bö macht Blau

Reputation: 13019

Activity A can choose its own request codes, and Activity B will never know which request code is used by A.

Which is no problem because request codes are purely local. Each Activity instance is separate from other Activity instances - they won't be mixed up just because they all implement the same method (like onCreate() or in your case onActivityResult() ).

Let's take a look at some lines from the source code for android.app.Activity, starting at line 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);
        }
    }
}

The comments in the quoted code snippet show that the request code is used to determine if there is a result to be returned.

Please note that the parameters for startActivityForResult(Intent intent, int requestCode, Bundle options) are passed into a method execStartActivity() from the Instrumentation class in the same package android.app.

But there are four other parameters to execStartActivity() which serve to identify the calling app and the current Activity instance (I won't go into details of the Binder framework here, but there is for example a youtube video on this topic):

Context who, IBinder contextThread, IBinder token, Activity target

Again, the request code is only used to determine if there is a result to be returned (for a negative request code, startActivityForResult() is handled just like startActivity())

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

Besides that, the request code is just passed back to the Activity which called startActivityForResult().

So if an Activity doesn't use the same request code for different types of requests, all is good.

Upvotes: 1

Jibran.
Jibran.

Reputation: 56

I think the library should give a parameter to specify request code by developer themselves for startActivityForResult, so they could never be conflicted in the same activity or fragment they have been called from.

Upvotes: 3

Related Questions