OkHttp Library – NetworkOnMainThreadException en simple post

Quiero usar la biblioteca OkHttp para redes en Android. Empecé con el simple ejemplo de publicación como está escrito en su sitio web:

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(); } 

Con esta llamada:

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

Esta llamada finaliza con NetworkOnMainThreadException .
Podría envolver la llamada con una AsyncTask, pero por lo que entiendo por los ejemplos, la biblioteca OkHttp ya debería haberse ocupado de eso … ¿Estoy haciendo algo mal?

Deberías usar el método async de OkHttp.

 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; } 

Y luego su respuesta se manejará en la callback (OkHttp 2.x):

 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 } } }); 

O 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 } } }); 

Eche un vistazo a sus recetas para ver más ejemplos: https://github.com/square/okhttp/wiki/Recipes

De acuerdo con los documentos OkHttp: admite llamadas de locking sincrónicas y llamadas asíncronas con devoluciones de llamadas. Su ejemplo está en el hilo principal y Android, ya que la versión 3.0 arroja esa excepción si intenta hacer llamadas de red en el hilo principal

La mejor opción es usarlo junto con la actualización y Gson: http://square.github.io/retrofit/ https://code.google.com/p/google-gson/

Estos son los ejemplos: http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-android/ http://heriman.net/?p=5

Si sigue estos pasos para implementar OKHTTP, definitivamente llamará a múltiples API en múltiples pantallas al aplicar solo dos líneas de código

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

Paso 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(); 

Paso 2: crea una clase de solicitud

/ ** * Creado por Deepak Sharma el 4/7/16. * Esta es una clase de solicitud HTTP que tiene los parámetros básicos. * Si quiere agregar algunos parámetros más, cree una subclase de esa clase * y agréguela a su subclase. No modifique esta clase. * /

  public class BaseHTTPRequest { private Context context; private String URL; private int requestCode; private List 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 getListParameters() { return listParameters; } public void setListParameters(List 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; } } 

Paso 4: Crea una clase de oyente

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

/ ** * Creado por Deepak Sharma el 4/7/16. * @email: dpsharma.sharma1@gmail.com * Esta es una clase simple de Java que te ayudará a solicitar / responder HTTP y arrojará la respuesta a tu actividad de correspondencia. * /

 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 requestParameters = requestModel.getListParameters(); for (int i=0; i1) { 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 } }); } } 

paso 5: desde la actividad que solicitas, implementa listener

 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; } } } }