编程语言
首页 > 编程语言> > android-GoogleAuthUtil.getToken()引发:RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

android-GoogleAuthUtil.getToken()引发:RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

作者:互联网

此GoogleAuthUtil getToken()调用:

String token = GoogleAuthUtil.getToken(appContext, accountName, scope);

偶尔会因以下异常而失败:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare():
ak: GooglePlayServicesNotAvailable
    at com.google.android.gms.auth.GoogleAuthUtil.a(Unknown Source)
    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
    at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)

因此(duh)显然是Google的代码正在尝试创建Handler :)但是我们正在从标准(非Looper)线程调用getToken(),并建议按照Google’s documentation进行所有异常处理,并且文档中明确指出“在非主线程阻塞环境中使用GoogleAuthUtil”.所以例如当然,不应在UI线程上调用它.

gplay文档中有一件事是模棱两可的:我们正在将Application上下文传递给getToken(),但是文档没有说是否期望特定的上下文,例如来自活动.其他人有一种或另一种经历吗?我不知道这怎么可能导致问题,但您永远不知道.

主要问题:如何恢复?目前,我们捕获了异常并放弃了,但这确实意味着我们无法为受影响的用户获得身份验证.

一如既往地感谢Googler的指导:)

谢谢!

解决方法:

我认为我们已经弄清楚了. RuntimeException来自getErrorDialog(),同时处理GooglePlayServicesAvailabilityException;关于异常处理的一些东西是从堆栈跟踪中排除的.这就是为什么失败如此罕见的原因-只有异常的设备配置会抛出该异常.

错误:类似于Google的文档示例,我们的处理程序执行了以下操作:

} catch (GooglePlayServicesAvailabilityException e) {
    int errorCode = e.getConnectionStatusCode();
    if (GooglePlayServicesUtil.isUserRecoverableError(errorCode)) {
        Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode, resolutionActivity, ...);

但这不起作用,因为您不能在非Looper线程上调用getErrorDialog().

固定:

Activity resolutionActivity = ...;

try {
    String token = GoogleAuthUtil.getToken(appContext, accountName, scope);
    ...
} catch (GooglePlayServicesAvailabilityException e) {
    final int errorCode = e.getConnectionStatusCode();
    if (GooglePlayServicesUtil.isUserRecoverableError(errorCode)) {
        resolutionActivity.runOnUiThread(new Runnable() {
            @Override public void run() {
                Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode, resolutionActivity, ...);
                errorDialog.show();

在发布并确认这是原因之后,我将进行更新,但这似乎是可能的.

如果这是问题所在,则应更新Google文档,因为它显示在后台线程上调用getErrorDialog().

我们已经发布了上述修复程序并解决了问题:应该在UI线程上调用GooglePlayServicesUtil.getErrorDialog().

标签:google-play-services,android
来源: https://codeday.me/bug/20191030/1965074.html