2015-01-25 9 views
20

Ich möchte OkHttp Bibliothek für das Netzwerk in Android verwenden. Ich begann mit dem einfachen Post Beispiel wie in ihrer Website geschrieben:OkHttp Library - NetworkOnMainThreadException auf einfache Post

public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); 

OkHttpClient client = new OkHttpClient(); 

String post(String url, String json) throws IOException { 
    RequestBody body = RequestBody.create(JSON, json); 
    Request request = new Request.Builder() 
     .url(url) 
     .post(body) 
     .build(); 
    Response response = client.newCall(request).execute(); 
    return response.body().string(); 
} 

Mit diesem Aufruf:

String response = post("http://www.roundsapp.com/post", json); 

Dieser Aufruf endet mit NetworkOnMainThreadException.
Ich könnte den Anruf mit einer AsyncTask, wickeln, aber soweit ich aus den Beispielen verstehe, sollte die OkHttp-Bibliothek schon darauf geachtet haben .. Mache ich etwas falsch?

+0

möglich Duplikat [android.os.NetworkOnMainThreadException] (http://stackoverflow.com/questions/6343166/ android-os-networkonmainthreadexception) Hast du überhaupt darüber nachgedacht, zuerst zu suchen? – Simon

+3

Es hat nichts damit zu tun .. Lesen Sie die Frage noch einmal. Besonders beschmutzte Teile. Denkst du darüber nach, zuerst zu lesen? –

+0

Ich habe die Frage gelesen und es hat alles damit zu tun. Sie sind Dong Netzwerk IO auf dem Hauptthread. Es spielt keine Rolle, was Sie ** denken ** die Bibliothek tut, es gibt nur eine Ursache für diese Ausnahme. – Simon

Antwort

39

Sie sollten OkHttp der Asynchron-Methode verwenden.

public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); 

OkHttpClient client = new OkHttpClient(); 

Call post(String url, String json, Callback callback) { 
    RequestBody body = RequestBody.create(JSON, json); 
    Request request = new Request.Builder() 
     .url(url) 
     .post(body) 
     .build(); 
    Call call = client.newCall(request); 
    call.enqueue(callback); 
    return call; 
} 

Und dann würde Ihre Antwort in den Callback (OkHttp 2.x) behandelt werden:

post("http://www.roundsapp.com/post", json, new Callback() { 
    @Override 
    public void onFailure(Request request, Throwable throwable) { 
    // Something went wrong 
    } 

    @Override public void onResponse(Response response) throws IOException { 
    if (response.isSuccessful()) { 
     String responseStr = response.body().string(); 
     // Do what you want to do with the response. 
    } else { 
     // Request not successful 
    } 
    } 
}); 

Oder OkHttp 3.x:

post("http://www.roundsapp.com/post", "", new Callback() { 
     @Override 
     public void onFailure(Call call, IOException e) { 
      // Something went wrong 
     } 

     @Override 
     public void onResponse(Call call, Response response) throws IOException { 
      if (response.isSuccessful()) { 
       String responseStr = response.body().string(); 
       // Do what you want to do with the response. 
      } else { 
       // Request not successful 
      } 
     } 
    }); 

Werfen Sie einen Blick auf ihre Rezepte für mehr Beispiele: https://github.com/square/okhttp/wiki/Recipes

+2

Sie sollten 'Response Response' entfernen, da' .enqueue (Callback) 'nichts zurückgibt + es sollte' void post ('stattdessen von 'String post (' –

4

Gemäß der OkHttp-Dokumentation: Es unterstützt sowohl synchrone blockierende Anrufe und asynchrone Anrufe mit Rückrufen. Ihr Beispiel ist auf Hauptthread und Android ab Version 3.0, dass die Ausnahme ausgelöst, wenn Sie versuchen, Netzanrufe auf Hauptthread zu tun

bessere Option ist, es zu benutzen, zusammen mit Retrofit und Gson: http://square.github.io/retrofit/ https://code.google.com/p/google-gson/

Hier Beispiele sind: http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-android/ http://heriman.net/?p=5

+0

Weiß jemand, ob es möglich ist, einen "PATCH" mit OkHttp zu machen? Ich habe gesucht und ich kann keine Beispiele finden. Alle Ideen und Vorschläge werden sehr geschätzt. – ito

+0

Es sollte dasselbe sein wie post(). Definition ist in Request-Klasse: öffentlichen Builder-Patch (RequestBody Körper) { Rücksende-Methode ("PATCH", Körper); } – kjurkovic

+0

Wie geht man mit der unterschiedlichen Antwort beim Nachrüsten um? –

0

Wenn Sie diese Schritte befolgen, um OKHTTP zu implementieren, dann werden Sie definitiv mehrere API auf mehreren Bildschirm aufrufen, indem nur zwei Zeilen Code Anwendung

UpdateListener updateListener = new UpdateListener(HitAPIActivity.this, baseHTTPRequest); 
updateListener.getJsonData(); 

Schritt 1:

baseHTTPRequest = new BaseHTTPRequest(); 
    // baseHTTPRequest.setURL("https://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demohttps://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo"); 
baseHTTPRequest.setURL("http://jsonparsing.parseapp.com/jsonData/moviesDemoItem.txt"); 
     baseHTTPRequest.setRequestCode(reqType); 
     baseHTTPRequest.setCachedRequired(true); 

     UpdateListener updateListener = new UpdateListener(HitAPIActivity.this, baseHTTPRequest); 
     updateListener.executeRequest(); 

Schritt 2: Erstellen Sie eine Anfrage Klasse

/** * Erstellt von Deepak Sharma am 07.04.16. * Dies ist eine HTTP-Anfrage-Klasse, die die grundlegenden Parameter hat. * Wenn Sie weitere Parameter hinzufügen möchten, erstellen Sie eine Unterklasse dieser Klasse * und fügen Sie sie mit Ihrer Unterklasse hinzu. Ändern Sie diese Klasse nicht. */

public class BaseHTTPRequest<T> { 

    private Context context; 
    private String URL; 
    private int requestCode; 
    private List<T> listParameters; 
    private String header; 
    private boolean isCachedRequired; 

    public Context getContext() { 
     return context; 
    } 
    public void setContext(Context context) { 
     this.context = context; 
    } 
    public void setURL(String URL) { 
     this.URL = URL; 
    } 
    public String getURL() { 
     return URL; 
    } 

    public int getRequestCode() { 
     return requestCode; 
    } 

    public void setRequestCode(int requestCode) { 
     this.requestCode = requestCode; 
    } 

    public List<T> getListParameters() { 
     return listParameters; 
    } 

    public void setListParameters(List<T> listParameters) { 
     this.listParameters = listParameters; 
    } 

    public String getHeader() { 
     return header; 
    } 

    public void setHeader(String header) { 
     this.header = header; 
    } 

    public boolean isCachedRequired() { 
     return isCachedRequired; 
    } 
    public void setCachedRequired(boolean cachedRequired) { 
     isCachedRequired = cachedRequired; 
    } 
} 

Schritt 4: Erstellen einer Listener-Klasse

Import android.util.Log; importieren com.google.gson.Gson; Import java.io.IOException; Importieren Sie dxswifi_direct.com.wifidirectcommunication.base.model.request.BaseHTTPRequest; importieren okhttp3.Call; importieren okhttp3.MediaType; importieren okhttp3.OkHttpClient; importieren okhttp3.Callback; importieren okhttp3.Request; importieren okhttp3.RequestBody; importieren okhttp3.Response;

/** * Erstellt von Deepak Sharma am 07.04.16. * @email: [email protected] * Dies ist eine einfache Java-Klasse, die Ihnen für HTTP-Anfrage/Antwort hilft und es wird * werfen Sie die Antwort auf Ihre Korrespondenz Aktivität. */

public class UpdateListener { 

    private OnUpdateViewListener onUpdateViewListener; 

    OkHttpClient okHttpClient = new OkHttpClient(); 
    BaseHTTPRequest mRequestModel; 
    private String mURL = null; 
    private Request mRequest = null; 

    public interface OnUpdateViewListener { 
     void updateView(String responseString, boolean isSuccess,int reqType); 
    } 

    public UpdateListener(OnUpdateViewListener onUpdateView, final BaseHTTPRequest requestModel) { 
     this.mRequestModel = requestModel; 
     this.onUpdateViewListener = onUpdateView; 

     if (requestModel.isCachedRequired()) 
     { 
      /*File httpCacheDirectory = new File(requestModel.getContext().getCacheDir(), "responses"); 
      Cache cache = null; 
      cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024); 
      if (cache != null) { 
       okHttpClient.setCache(cache); 
      }*/ 
     } 

     /*mURL = null; 
     if (requestModel.getListParameters()!=null && requestModel.getListParameters().size()>0) 
     { 
      HttpUrl.Builder urlBuilder = HttpUrl.parse(requestModel.getURL()).newBuilder(); 
      List<RequestParameter> requestParameters = requestModel.getListParameters(); 
      for (int i=0; i<requestParameters.size();i++) 
      { 
       urlBuilder.addQueryParameter(requestParameters.get(i).getKey(),requestParameters.get(i).getValue()); 
      } 
      mURL = urlBuilder.build().toString(); 
     } 
     else 
     { 
      mURL = requestModel.getURL(); 
     }*/ 

      mURL = requestModel.getURL(); 
     if (mRequestModel.getListParameters()!=null && mRequestModel.getListParameters().size()>1) 
     { 
      MediaType JSON = MediaType.parse("application/json; charset=utf-8"); 
      mRequest = new Request.Builder() 
        .url(mURL) 
        .post(RequestBody.create(JSON, new Gson().toJson(BaseHTTPRequest.class))) 
        .build(); 
     } 
     else 
     { 
      mRequest = new Request.Builder() 
        .url(mURL) 
        .build(); 
     } 

    } 

    public void executeRequest() 
    { 
     Call call = okHttpClient.newCall(mRequest); 
     call.enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       e.printStackTrace(); 
       onUpdateViewListener.updateView(NetworkException.getErrorMessage(e), false, mRequestModel.getRequestCode()); 
      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       if (!response.isSuccessful()) { 
        // You can also throw your own custom exception 
        throw new IOException("Unexpected code " + response); 
       } else { 
        Log.i("Response:",response.toString()); 
        Log.i("Response body:",response.body().toString()); 
        Log.i("Response message:",response.message()); 
        onUpdateViewListener.updateView(response.body().string(),true, mRequestModel.getRequestCode()); 
       } 
       // do something wih the result 
      } 
     }); 
    } 
} 

Schritt 5: Von der Aktivität, die Sie anfordern, implementieren Zuhörer

public class HitAPIActivity extends AppCompatActivity implements View.OnClickListener, UpdateListener.OnUpdateViewListener{ 

@Override 
    public void updateView(final String responseString, boolean isSuccess, int reqType) { 

if (isSuccess) 
     { 

if (!responseString.contains("failure") 
        && !responseString.contains("Error")) { 
       // Handle request on the basis of Request Type. 
       switch (reqType) { 
        case ApiConstants.GET_CONTACTS: 

break; 

default: 
break; 

} 

} 
} 

}