2016-04-12 2 views
0

Zuvor würde ich einfach die response.body().string() zu OnPostExecute() Methode asyncTask zu TextViews der aktualisieren. okHttp scheint diese Option nicht zu haben. Wo ist das Äquivalent oder wie erreiche ich das?Der Versuch, das Callback-Szenario okHttp zu implementieren. Nach Abschluss gibt es keine onPostExecute, um die UI zu ändern

//Call to server to echo MySQL query 
    private void usersInZone() { 
       if (!isNetworkAvailable()) return; 
       rotate(true); 
       OkHttpClient client = new OkHttpClient(); 
       RequestBody formBody = new FormBody.Builder() 
         .add("userId", String.valueOf(userId)) 
         .add("channel", String.valueOf(subport + port)) 
         .build(); 
       Request request = new Request.Builder() 
         .url(SITE_URL + "inZone.php") 
         .post(formBody) 
         .build(); 

       Call users = client.newCall(request); 
       users.enqueue(caller); 
      } 

//okHttp Callback to parse echo response 
    caller = new Callback() { 
       @Override 
       public void onFailure(Call call, IOException e) { 
        if (RS != null) RS.makePoor(true); 
       } 

       @Override 
       public void onResponse(Call call, Response response) throws IOException { 
        LOG.l(String.valueOf(call)); 
        if (response.isSuccessful()) { 
         try { 
          JSONObject data = new JSONObject(response.body().string()); 
          updateFields(getString(R.string.inzone) + data.getInt("total") + "]", String.valueOf(data.getInt("zone"))); 
         } catch (JSONException e) { 
          LOG.l("JSONException" + e); 
         } 
        } else if (RS != null) RS.makePoor(true); 

       } 
      }; 
//UI textViews i'm needing to update with the echoed results 
    private void updateFields(String total, String channelTotal){ 
      subtitle.setText(total); 
      tvusercount.setText(channelTotal); 
     } 
+0

AFAIK, 'onResponse()' wird im Hauptanwendungs-Thread aufgerufen. Sie können dort Ihre Benutzeroberfläche aktualisieren. – CommonsWare

+0

Erhalte diesen Fehler ... android.view.ViewRootImpl $ CalledFromWrongThreadException: Nur der ursprüngliche Thread, der eine Ansichtshierarchie erstellt hat, kann seine Ansichten berühren. –

+0

Nun, ich weiß nicht, wie Sie die Ansichten erstellen. Wenn wir annehmen, dass sie konventionell erzeugt werden (dh auf dem Hauptanwendungs-Thread), dann können Sie 'runOnUiThread()' (aufgerufen auf eine 'Aktivität') oder' post() '(aufgerufen auf einer' Ansicht') zu verwenden Führen Sie '' updateFields() 'im Hauptanwendungs-Thread aus. Ich weiß, dass Retrofit seine asynchronen Ergebnisse im Hauptanwendungs-Thread liefert. Ich hatte den Eindruck, dass OkHttp das auch getan hat, obwohl ich denke, dass ich nur seine synchrone API benutzt habe. – CommonsWare

Antwort

1

Der Callback wird nicht im Hauptthread aufgerufen. Wenn Sie die Benutzeroberfläche aktualisieren müssen, eine einfache Möglichkeit, dies zu tun ist, um eine Klasse zu erstellen, die Callback implementiert und poste die Elemente der Benutzeroberfläche wie folgt:

public abstract class UIMainCallback implements Callback { 
    private static final Handler mUIHandler = new Handler(Looper.getMainLooper()); 

    abstract void failure(Request request, IOException e); 

    abstract void response(Response response); 

    @Override 
    public void onFailure(final Request request, final IOException e) { 
     mUIHandler.post(new Runnable() { 
      @Override 
      public void run() { 
       failure(request, e); 
      } 
     }); 
    } 

    @Override 
    public void onResponse(final Response response) throws IOException { 
     mUIHandler.post(new Runnable() { 
      @Override 
      public void run() { 
       response(response); 
      } 
     }); 
    } 
} 

Dann wird Ihr Caller kann nur die UIMainCallback implementieren statt der Schnittstelle.

2

Wo ist das Äquivalent oder, wie dies zu erreichen?

OkHttps onResponse() wird nicht am Haupt-Thread aufgerufen. Wenn Sie die Benutzeroberfläche in onResponse aktualisieren möchten, müssen Sie diese Aufgabe an den UI-Thread delegieren. Verwenden Handler und Buchung Runnable ist eine Möglichkeit, dies zu tun.

Verwandte Themen