“从您的主线程调用它可能会导致死锁和/或 ANR,同时从 GoogleAuthUtil(Android 中的 Google Plus 集成)获取 accessToken”
Posted
技术标签:
【中文标题】“从您的主线程调用它可能会导致死锁和/或 ANR,同时从 GoogleAuthUtil(Android 中的 Google Plus 集成)获取 accessToken”【英文标题】:"Calling this from your main thread can lead to deadlock and/or ANRs while getting accesToken" from GoogleAuthUtil(Google Plus integration in Android) 【发布时间】:2013-07-06 23:43:25 【问题描述】:在我的 android 应用程序中,我试图从 GoogleAuthUtil 获取 AccessToken,如下所示:
accessToken = GoogleAuthUtil.getToken(this, mPlusClient.getAccountName(), "oauth2:" + SCOPES);
但是在这一行我得到如下错误:
E/GoogleAuthUtil(4696):从您的主线程调用它可能会导致死锁和/或 ANR E/GoogleAuthUtil(4696): java.lang.IllegalStateException: 从你的主线程调用它会导致死锁 E/GoogleAuthUtil(4696):在 com.google.android.gms.auth.GoogleAuthUtil.b(未知来源) E/GoogleAuthUtil(4696):在 com.google.android.gms.auth.GoogleAuthUtil.getToken(未知来源) E/GoogleAuthUtil(4696):在 com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
这个问题有什么解决办法吗?任何帮助将不胜感激。
【问题讨论】:
嘿@Ponting,这曾经对我有用,但就在几天前它停止工作,现在它抛出这个错误 com.google.android.gms.auth.GoogleAuthException: Unknown。知道为什么吗?我的瞄准镜有问题吗? gist.github.com/lawloretienne/7351151 【参考方案1】: Thread CrearEventoHilo = new Thread()
public void run()
//do something that retrun "Calling this from your main thread can lead to deadlock"
;
CrearEventoHilo.start();
CrearEventoHilo.interrupt();
public class Foo
MyThread mTh;
void cantBeBothered()
mTh = new MyThread( /*...*/ );
mTh.run();
mTh.start();
void imFinishedNowWaitingForThread()
mTh.join();
void imOutKillingOffPendingThread()
mTh.interrupt();
// .....
private class MyThread extends Thread
// ...;
MyThread( /*...*/)
// this... = ...;
public void run()
doSomething( /*this...*/ );
【讨论】:
如果您添加有关其工作原理的说明,您的答案将更有价值。 为什么要调用 interrupt() ?【参考方案2】:用这样的 AsyncTask 试试:
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>()
@Override
protected String doInBackground(Void... params)
String token = null;
try
token = GoogleAuthUtil.getToken(
MainActivity.this,
mGoogleApiClient.getAccountName(),
"oauth2:" + SCOPES);
catch (IOException transientEx)
// Network or server error, try later
Log.e(TAG, transientEx.toString());
catch (UserRecoverableAuthException e)
// Recover (with e.getIntent())
Log.e(TAG, e.toString());
Intent recover = e.getIntent();
startActivityForResult(recover, REQUEST_CODE_TOKEN_AUTH);
catch (GoogleAuthException authEx)
// The call is not ever expected to succeed
// assuming you have already verified that
// Google Play services is installed.
Log.e(TAG, authEx.toString());
return token;
@Override
protected void onPostExecute(String token)
Log.i(TAG, "Access token retrieved:" + token);
;
task.execute();
SCOPES
是一个空格分隔的 OAuth 2.0 范围字符串列表。例如SCOPES
可以定义为:
public static final String SCOPES = "https://www.googleapis.com/auth/plus.login "
+ "https://www.googleapis.com/auth/drive.file";
这些代表您的应用向用户请求的权限。此示例中请求的范围记录在此处:
https://developers.google.com/+/api/oauth https://developers.google.com/drive/android/files【讨论】:
这里的范围是什么? 编辑了我的答案以解释 SCOPES。 如果你不需要访问驱动器,你应该从范围中删除'developers.google.com/drive/android/files' 是否也可以使用某些 Android Google API 检索访问令牌过期时间?还是仅通过 HTTPS 请求? @Lee 你有任何关于获取刷新令牌的线索吗?【参考方案3】:为您的互联网代码使用单独的线程。错误告诉应用程序中正在运行更耗时的过程,这里是互联网。所以使用单独的线程或异步任务。
查看此链接NetworkOnMainThreadException
希望对你有所帮助。
【讨论】:
【参考方案4】:E/GoogleAuthUtil(4696): java.lang.IllegalStateException: 调用这个 从你的主线程可能会导致死锁
听起来您需要在单独的线程上执行此操作,您尝试过吗?
Here你可以找到关于Android线程的信息。
【讨论】:
我尝试在新线程下运行上面的代码:new Thread(new Runnable() public void run() .start(); ..但它给出的错误是 GoogleAuthUtil.getToken无法在可运行方法上运行。以上是关于“从您的主线程调用它可能会导致死锁和/或 ANR,同时从 GoogleAuthUtil(Android 中的 Google Plus 集成)获取 accessToken”的主要内容,如果未能解决你的问题,请参考以下文章