在我的开发中,我使用registerForActivityResult
来实现google登录。在我将片段依赖项升级到1.3.0-beta 01之前,一切都运行正常。应用程序当前崩溃,错误为
java.lang.IllegalStateException:生命周期所有者SignupChoicesFragment{8 e0 e269}(193105 b 9-afe 2 -4941-a368- 266 dbc 433258)id= 0x 7 f090139}在当前状态为“已恢复”时正在尝试注册。生命周期所有者必须先调用注册,然后才能启动。
我在oncreate之前使用过这个函数,使用的是惰性加载,但是它仍然不起作用。
class SignupChoicesFragment : DaggerFragment() {
@Inject
lateinit var viewModelProviderFactory: ViewModelFactory
val userViewModel: UserViewModel by lazy {
ViewModelProvider(this, viewModelProviderFactory).get(UserViewModel::class.java)
}
@Inject
lateinit var mGoogleSignInClient:GoogleSignInClient
val arg:SignupChoicesFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_signup_choices, container, false)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
google_sign_in_button.setOnClickListener {
val intent = mGoogleSignInClient.signInIntent
val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult(), ActivityResultCallback {result->
if (result.resultCode == Activity.RESULT_OK) {
val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
task.addOnCompleteListener {
if (it.isSuccessful) {
val account: GoogleSignInAccount? =
it.getResult(ApiException::class.java)
val idToken = it.result?.idToken
val email = account?.email
val lastName = account?.familyName
val firstName = account?.givenName
val otherName = account?.displayName
val imageUrl = account?.photoUrl
val category = arg.category
val newUser = User()
newUser.firstName = firstName
newUser.lastName = lastName
newUser.otherName = otherName
newUser.category = category
newUser.email = email
newUser.imageUrl = imageUrl.toString()
userViewModel.currentUser = newUser
newUser.token = idToken
i(title, "idToken $idToken")
requireActivity().gdToast("Authentication successful", Gravity.BOTTOM)
val action = SignupChoicesFragmentDirections.actionSignupChoicesFragmentToEmailSignupFragment()
action.newUser = newUser
goto(action)
} else {
requireActivity().gdToast(
"Authentication Unsuccessful",
Gravity.BOTTOM
)
Log.i(title, "Task not successful")
}
}
} else {
Log.i(title, "OKCODE ${Activity.RESULT_OK} RESULTCODE ${result.resultCode}")
}
}).launch(intent)
}
}
7条答案
按热度按时间bxgwgixi1#
对我来说,问题是我在
onClickListener
中调用了registerForActivityResult
,而onClickListener
只在单击按钮时调用(此时应用处于RESUMED状态)。将调用移出按钮的onClickListener
并移入Activity的onCreate
方法即可解决此问题。ttygqcqt2#
从文件中引用
在创建片段或Activity之前调用registerForActivityResult()是安全的,这样就可以在为返回的ActivityResultLauncher示例声明成员变量时直接使用该方法。注意:虽然在创建片段或Activity之前调用registerForActivityResult()是安全的,但在片段或Activity的生命周期达到CREATED之前,您无法启动ActivityResultLauncher。
因此,要解决您的问题,请将您的register调用移出
onCreate()
,并将其置于fragment
范围内,然后在google_sign_in_button上调用click-listener
启动函数注意:如果您使用的是Kotlin-Android-Extention,请将您的
click-listener
调用移动到onViewCreated()
5uzkadbs3#
如果你使用的是片段,请确保你没有在Activity上执行
registerForActivityResult
。片段也有一个registerForActivityResult
,这是你应该使用的。fkaflof64#
在创建片段或Activity之前调用registerForActivityResult()是安全的,这允许在为返回的ActivityResultLauncher示例声明成员变量时直接使用该方法。
您应该在创建视图之前调用registerForActivityResult。成员变量或onCreate()
ercv8c1e5#
您必须将
val launcher = registerForActivityResult...
从setOnClickListener
中删除,然后将其保存在变量中,在您的示例中为launcher
,并在setOnClickListener
中使用.launch执行变量,在您的示例中为launcher
。您的代码将如下所示
来源:https://medium.com/codex/android-runtime-permissions-using-registerforactivityresult-68c4eb3c0b61
gopyfrb36#
如果你使用的是第三方库,那么你可能会在代码中看不到“registerForActivityResult”,但是它应该出现在同一个库提供的类中。所以在这种情况下,我建议把与该库相关的行从任何监听器移到onCreate方法中。
例如─
////从侦听器中移除其他代码并移入onCreate
///您可以在侦听器中只保留必需的行
就是这样!
txu3uszq7#
发现了同样的问题,并设法得到一些魔术的工作。
在我的例子中,它发生在
Activity
中,所以我这样做:其中
navigator.gotoScreenForResult
看起来如下所示:只需确保
setupViews
在onCreate
中完成,而不是在恢复步骤中完成。