You must ensure the ActivityResultLauncher is registered before calling launch()

3.2k Views Asked by At

In some android device, I'm getting this IllegalStateException in ActivityResultLauncher

Fatal Exception: java.lang.IllegalStateException: Attempting to launch an unregistered ActivityResultLauncher with contract androidx.activity.result.contract.ActivityResultContracts$StartActivityForResult@3325833 and input Intent { act=com.google.android.gms.auth.GOOGLE_SIGN_IN pkg=com.xyz.app cmp=com.xyz.app/com.google.android.gms.auth.api.signin.internal.SignInHubActivity (has extras) }. You must ensure the ActivityResultLauncher is registered before calling launch().
       at androidx.activity.result.ActivityResultRegistry$2.launch(ActivityResultRegistry.java:168)
       at androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:47)
       at com.xyz.app.ui.auth.login.LoginActivity.doAuth$lambda$22$lambda$20(LoginActivity.kt:318)
       at com.xyz.app.ui.auth.login.LoginActivity.$r8$lambda$zt4kZAeP81QjQuIivycpvJCWE4o()
       at com.xyz.app.ui.auth.login.LoginActivity$$ExternalSyntheticLambda7.onComplete(:4)
       at com.google.android.gms.tasks.zzi.run(com.google.android.gms:play-services-tasks@@18.0.1:1)
       at android.os.Handler.handleCallback(Handler.java:790)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:6977)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:528)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:910)

I have register launcher in onCreate() method. When activity was destroyed and recreated due to configuration change such as when orientation was changed, I have re-initialize the ActivityResultLauncher inside onCreate before calling the launch again and also put a Null check before Launching it.

private lateinit var resultLauncherForGmailSignIn: ActivityResultLauncher<Intent>

public class LoginActivity extends AppCompatActivity {
    
    private ActivityResultLauncher<Intent> myLauncher;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
         resultLauncherForGmailSignIn =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
                val intentData: Intent? = result.data
                intentData?.let {
                    loginViewModel.signInWithGmail(it)
                }
            }
      
        findViewById(R.id.myButton).setOnClickListener(v -> {
                    if (this::resultLauncherForGmailSignIn.isInitialized) {
                        resultLauncherForGmailSignIn.launch(signInIntent)
                    }
        });
    }
}
1

There are 1 best solutions below

2
Ariczek On

Well, you have answered yourself. You are calling register in the second onCreate call. That is wrong.

You can register it as a variable inside Activity class, something like

class MyActiviy : AppCompatActivity() {

    val resultLauncherForGmailSignIn: ActivityResultLauncher<Intent> = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()) {
        ...
    }

This will ensure, the register is invoked only once at creation, but not for recreate.

Or you can check the savedInstanceState parameter, it will not be null in case of recreate scenario.

Related Questions in ILLEGALSTATEEXCEPTION