2014-10-10 12 views
5

Ich implementiere die Google Drive APIs in meiner Android-Anwendung. Ich möchte PendingResult # setResultCallback() nicht verwenden, stattdessen möchte ich PendingResult # await() verwenden, damit ich das Ergebnis in der nächsten Zeile abrufen kann und nicht warten muss. Dies ist kein Problem, da alles im Hintergrund läuft.Google Drive API await() UI Thread Fehler

Allerdings jedes Mal, wenn ich call have(), bekomme ich den folgenden Fehler. Ich habe versucht, einen einzelnen Anruf an die Google Drive API zu senden, die in asyncTask, Thread, IntentService, Dienst mit AsyncTask und einem Dienst mit einem Thread awarts() verwendet. Ich habe jedes Mal den folgenden Fehler erhalten. Ich habe versucht, Looper.prepare() in meinen Thread-Implementierungen aufzurufen, aber es hat nichts gelöst.

Ist noch jemand in dieses Problem geraten?

java.lang.IllegalStateException: await must not be called on the UI thread 
     at com.google.android.gms.internal.hm.a(Unknown Source) 
     at com.google.android.gms.common.api.a$a.await(Unknown Source) 
     at [OMITTED].GoogleDriveManager$2.onConnected(GoogleDriveManager.java:83) 
     at com.google.android.gms.internal.hc.c(Unknown Source) 
     at com.google.android.gms.common.api.c.eK(Unknown Source) 
     at com.google.android.gms.common.api.c.d(Unknown Source) 
     at com.google.android.gms.common.api.c$2.onConnected(Unknown Source) 
     at com.google.android.gms.internal.hc.c(Unknown Source) 
     at com.google.android.gms.internal.hc.cp(Unknown Source) 
     at com.google.android.gms.internal.hb$h.b(Unknown Source) 
     at com.google.android.gms.internal.hb$h.d(Unknown Source) 
     at com.google.android.gms.internal.hb$b.fv(Unknown Source) 
     at com.google.android.gms.internal.hb$a.handleMessage(Unknown Source) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:136) 
     at android.app.ActivityThread.main(ActivityThread.java:5146) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612) 
     at dalvik.system.NativeStart.main(Native Method) 

Dies ist der Code, den ich die API zu testen, bin mit:

 apiClient = new GoogleApiClient.Builder(mContext) 
      .addApi(Drive.API) 
      .addScope(Drive.SCOPE_APPFOLDER) 
      .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { 
       @Override 
       public void onConnected(Bundle bundle) { 
        LogUtil.log(TAG, "onConnected()"); 
        connected = true; 

        DriveApi.ContentsResult result = Drive.DriveApi.newContents(apiClient).await(); 

       } 
       @Override 
       public void onConnectionSuspended(int i) { 
        LogUtil.log(TAG, "onConnectionSuspended()"); 
        connected = false; 
       } 
      }) 
      .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { 
       @Override 
       public void onConnectionFailed(ConnectionResult result) { 
        LogUtil.log(TAG, "onConnectionFailed()"); 
        connected = false; 
       } 
      }) 
      .build(); 
    apiClient.connect(); 
+0

wo ist dein AsyncTask? – tyczj

+0

Ich habe den zweiten Codeblock innerhalb der doInBackground-Methode einer asynctask ausgeführt und mir wurde der Fehler im zweiten Codeblock angezeigt. –

+0

können Sie bitte zeigen, wie Sie es implementiert haben, weil Sie es offensichtlich nicht richtig gemacht haben – tyczj

Antwort

6

apiClient.connect() ist ein asynchroner Vorgang, also warum es innerhalb eines AsyncTask Aufruf hilft nicht (läuft auf einem Hintergrund-Thread verbinden Doesn 't help, wenn onConnected() im UI-Thread aufgerufen wird.

Stattdessen können Sie eine AsyncTask von Ihrem onConnected() Callback starten - dass die doInBackground() von AsyncTask dann Drive.DriveApi.newContents(apiClient).await() aufrufen könnte.

Natürlich gibt es keine Notwendigkeit jemals await() zu nennen - setResultCallback() verwenden, um asynchron für newContents() zu warten zu vervollständigen:

@Override 
public void onConnected(Bundle bundle) { 
    LogUtil.log(TAG, "onConnected()"); 
    connected = true; 

    Drive.DriveApi.newContents(apiClient).setResultCallback(
     new ResultCallback<DriveApi.ContentsResult>() { 
    @Override 
    public void onResult(DriveApi.ContentsResult result) { 
     // Use result 
    } 
    }); 
} 
+0

Dies macht jetzt Sinn. Ich verwende stattdessen .blockingConnect() und alles funktioniert jetzt. Vielen Dank! –

+1

Wenn diese Antwort geholfen hat, bitte akzeptieren Sie es – ianhanniballake

+0

Wie bekommt man das Ergebnis aus der anonymen inneren Klasse und zurück zu der aufrufenden Funktion. Wird das nicht verhindert? – Hephaestus