You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中ActivityResultLauncher未注册异常求助

解决ActivityResultLauncher未注册的IllegalStateException

问题根源

异常触发于Google登录异步任务的回调中调用launch():当点击按钮发起登录请求后,若Activity因配置变更(如横竖屏切换)销毁重建,异步回调会持有旧Activity实例的ActivityResultLauncher引用,而旧实例的launcher已被系统注销,此时调用launch()就会触发未注册异常——你在点击事件里的非空检查只覆盖了同步场景,没处理异步回调的生命周期错位问题。

具体解决办法

办法1:用弱引用持有Activity,回调中检查状态

将Activity的引用改为弱引用,在异步回调中先确认Activity处于活跃状态,再使用当前实例的launcher:

class LoginActivity : AppCompatActivity() {
    private lateinit var resultLauncherForGmailSignIn: ActivityResultLauncher<Intent>
    // 用弱引用持有Activity
    private val activityWeakRef = WeakReference(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        // 注册launcher
        resultLauncherForGmailSignIn = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            result.data?.let { loginViewModel.signInWithGmail(it) }
        }

        findViewById<Button>(R.id.myButton).setOnClickListener {
            // 发起Google登录异步请求
            val signInIntent = GoogleSignIn.getClient(this, gso).signInIntent
            GoogleSignIn.getClient(this, gso).silentSignIn()
                .addOnCompleteListener { task ->
                    val currentActivity = activityWeakRef.get()
                    // 检查Activity是否活跃且launcher已初始化
                    if (currentActivity != null && !currentActivity.isFinishing && !currentActivity.isDestroyed) {
                        if (currentActivity::resultLauncherForGmailSignIn.isInitialized) {
                            currentActivity.resultLauncherForGmailSignIn.launch(signInIntent)
                        }
                    }
                }
        }
    }
}

办法2:用ViewModel+LiveData实现生命周期安全的launch

将launch操作通过LiveData通知Activity,确保只有在Activity活跃时才执行:

  1. 在LoginViewModel中定义LiveData:
class LoginViewModel : ViewModel() {
    // 用于通知Activity发起登录跳转
    private val _launchGmailSignIn = MutableLiveData<Intent?>()
    val launchGmailSignIn: LiveData<Intent?> = _launchGmailSignIn

    fun triggerGmailSignIn(intent: Intent) {
        _launchGmailSignIn.postValue(intent)
    }
}
  1. 在LoginActivity中观察LiveData,处理launch:
class LoginActivity : AppCompatActivity() {
    private lateinit var resultLauncherForGmailSignIn: ActivityResultLauncher<Intent>
    private val loginViewModel by viewModels<LoginViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        // 注册launcher
        resultLauncherForGmailSignIn = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            result.data?.let { loginViewModel.signInWithGmail(it) }
        }

        // 观察LiveData,在Activity活跃时执行launch
        loginViewModel.launchGmailSignIn.observe(this) { intent ->
            intent?.let {
                resultLauncherForGmailSignIn.launch(it)
            }
        }

        findViewById<Button>(R.id.myButton).setOnClickListener {
            val signInIntent = GoogleSignIn.getClient(this, gso).signInIntent
            GoogleSignIn.getClient(this, gso).silentSignIn()
                .addOnCompleteListener { task ->
                    // 通知ViewModel触发跳转
                    loginViewModel.triggerGmailSignIn(signInIntent)
                }
        }
    }
}

办法3:在Activity销毁时取消异步回调

在Activity的onDestroy()方法中移除异步任务的回调,避免在Activity销毁后执行launch:

class LoginActivity : AppCompatActivity() {
    private lateinit var resultLauncherForGmailSignIn: ActivityResultLauncher<Intent>
    // 保存异步任务引用,用于取消回调
    private var signInTask: Task<GoogleSignInAccount>? = null
    // 保存回调引用
    private val signInCompleteListener = OnCompleteListener<GoogleSignInAccount> { task ->
        // 执行launch逻辑
        if (this::resultLauncherForGmailSignIn.isInitialized) {
            resultLauncherForGmailSignIn.launch(signInIntent)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        resultLauncherForGmailSignIn = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            result.data?.let { loginViewModel.signInWithGmail(it) }
        }

        findViewById<Button>(R.id.myButton).setOnClickListener {
            val signInIntent = GoogleSignIn.getClient(this, gso).signInIntent
            signInTask = GoogleSignIn.getClient(this, gso).silentSignIn()
            signInTask?.addOnCompleteListener(signInCompleteListener)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // 移除回调,避免Activity销毁后执行
        signInTask?.removeOnCompleteListener(signInCompleteListener)
    }
}

内容的提问来源于stack exchange,提问作者Andyson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 17:47:07