“从您的主线程调用它可能会导致死锁和/或 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”的主要内容,如果未能解决你的问题,请参考以下文章