web-dev-qa-db-fra.com

OkHttp Library - NetworkOnMainThreadException sur un message simple

Je souhaite utiliser OkHttp library pour la mise en réseau dans Android . J'ai commencé par le simple exemple de post écrit sur leur site 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();
}

Avec cet appel:

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

Cet appel se termine par NetworkOnMainThreadException.
Je pourrais conclure l'appel avec une AsyncTask, mais, d'après ce que j'ai compris des exemples, la bibliothèque OkHttp aurait déjà dû s'en occuper ... __ Est-ce que je fais quelque chose de mal?

22
Aviv Ben Shabat

Vous devriez utiliser la méthode asynchrone d'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;
}

Et puis votre réponse serait traitée dans le rappel (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
    }
  }
});

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

Jetez un oeil à leurs recettes pour plus d'exemples: https://github.com/square/okhttp/wiki/Recipes

46
se_bastiaan

Selon la documentation OkHttp: Il prend en charge les appels de blocage synchrone et les appels asynchrones avec callbacks . Votre exemple est sur le thread principal et Android depuis la version 3.0 lève cette exception si vous essayez d'effectuer des appels réseau sur le thread principal.

La meilleure option consiste à l’utiliser avec retrofit et Gson: http://square.github.io/retrofit/https://code.google.com/p/google- gson/

Voici les exemples: http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-Android/http: // heriman .net /? p = 5

4
kjurkovic

Si vous suivez ces étapes pour implémenter OKHTTP, vous appellerez certainement plusieurs API sur plusieurs écrans en appliquant seulement deux lignes de code.

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

Étape 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();

Étape 2: Créer une classe de demande

/** * Créé par Deepak Sharma le 4/7/16 . * Ceci est une classe de requête HTTP qui a les paramètres de base . * Si vous souhaitez ajouter quelques paramètres supplémentaires, créez une sous-classe de cette classe * et ajouter avec votre sous-classe. Ne modifiez pas cette classe . * /

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

étape 4: Créer une classe d'écoute

importer Android.util.Log; importer com.google.gson.Gson; importer Java.io.IOException; importer dxswifi_direct.com.wifidirectcommunication.base.model.request.BaseHTTPRequest; importer okhttp3.Call; importer okhttp3.MediaType; importer okhttp3.OkHttpClient; importer okhttp3.Callback; importer okhttp3.Request; .Réponse;

/** * Créé par Deepak Sharma le 4/7/16 . * @ mail: [email protected] * Ceci est une classe Java simple qui vous aidera pour la requête/réponse HTTP et ce sera * jeter la réponse à votre activité de correspondance . * /

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

étape 5: à partir de l'activité que vous demandez, implémentez 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;

}

}
}

}
0
Maddy