Attempting to launch an unregistered ActivityResultLauncher

Viewed 2072

Sometimes I'm getting this IllegalStateException, and it says that you must ensure the ActivityResultLauncher is registered before calling launch(). But there is no method to check if ActivityResultLauncher is registered. How can I solve this and why this may happen? Also, it's not clear when to call unregister() method, any examples?

3 Answers

Be aware to register your activityResultLauncher in onCreate method to prevent side-effect

public class MyActiviy extends AppCompatActivity {
    .
    .
    .

    private ActivityResultLauncher<Intent> myLauncher;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //some stuff

        // Register your launcher here
        myLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getResultCode() == RESULT_OK && result.getData() != null) {
                Intent data = result.getData();
            }
        });
      
        findViewById(R.id.myButton).setOnClickListener(v -> {
            // call `launch` after user click on button or something like that
            Intent intent = new Intent(this, TargetActivity.class);
            myLauncher.launch(intent);
        });
    }

}

Refere to Google doc :

When using the ActivityResultRegistry APIs, it's strongly recommended to use the APIs that take a LifecycleOwner, as the LifecycleOwner automatically removes your registered launcher when the Lifecycle is destroyed. However, in cases where a LifecycleOwner is not available, each ActivityResultLauncher class allows you to manually call unregister() as an alternative.

Take a look at Here

I have been experiencing the same issue for the past 1 month. After updating dependencies and Gradle. But I have managed to fix this after some experiments.

@Override
protected void onDestroy() {
    super.onDestroy();
     someActivityResultLauncher = null;
}

and adding null check

 if(someActivityResultLauncher !=null)
      someActivityResultLauncher.launch(consentIntent);

Let me explain, My app had 2 activities. Phone number & verification activity. I had a broadcast which receives OTP message and launch(). If the broadcast has received a message and the user is not on verification activity. The app would crash on Broadcast. Illegal state exception

 Exception java.lang.RuntimeException

Exception java.lang.RuntimeException:
  at android.app.LoadedApk$ReceiverDispatcher$Args.run (LoadedApk.java:972)
  at android.os.Handler.handleCallback (Handler.java:743)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:150)
  at android.app.ActivityThread.main (ActivityThread.java:5621)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:794)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:684)
Caused by java.lang.IllegalStateException:
  at androidx.activity.result.ActivityResultRegistry$2.launch (ActivityResultRegistry.java:168)
  at androidx.activity.result.ActivityResultLauncher.launch (ActivityResultLauncher.java:47)
  at com.jazz.pakistani.drama.videos.deikho.Activities.Credentials.VerifyPassword$2.onReceive (VerifyPassword.java:289)
  at android.app.LoadedApk$ReceiverDispatcher$Args.run (LoadedApk.java:962)  

This can also happen when you're activity was destroyed and recreated due to configuration change such as when orientation was changed. You must re-initialize the ActivityResultLauncher inside onCreate or onStart before calling the launch again.

Related