Библиотека OkHttp-NetworkOnMainThreadException на простой пост
Я хочу использовать OkHttp библиотека для сетей в Android. Я начал с простого примера 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();
}
С этим вызовом:
String response = post("http://www.roundsapp.com/post", json);
этот вызов заканчивается на NetworkOnMainThreadException.
я мог бы обернуть вызов AsyncTask, но, насколько я понимаю из примеров, библиотека OkHttp уже должна была позаботиться об этом..
Я делаю что-то не так?
3 ответов
вы должны использовать асинхронный метод 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;
}
и тогда ваш ответ будет обработан в обратном вызове (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
}
}
});
Или 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
}
}
});
взгляните на их рецепты для Больше примеров:https://github.com/square/okhttp/wiki/Recipes
согласно документам OkHttp: Он поддерживает как синхронные блокирующие вызовы, так и асинхронные вызовы с обратными вызовами. Ваш пример находится в main thread и Android, так как версия 3.0 выдает это исключение, если вы пытаетесь выполнить сетевые вызовы в main thread
лучший вариант использовать его вместе с retrofit и Gson: http://square.github.io/retrofit/ https://code.google.com/p/google-gson/
здесь образцы: http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-android/ http://heriman.net/?p=5
если вы выполните эти шаги для реализации OKHTTP, то определенно вы вызовете несколько API на нескольких экранах, применяя только две строки кода
UpdateListener updateListener = new UpdateListener(HitAPIActivity.this, baseHTTPRequest);
updateListener.getJsonData();
Шаг 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();
Шаг 2: Создайте класс запроса
/** * Создано Deepak Sharma на 4/7/16. * Это класс HTTP-запроса, который имеет основные параметры. * Если вы хотите добавить еще несколько параметров, сделайте подкласс этого класса * и добавить с вашим подклассом. Не изменять этот класс. */
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;
}
}
Шаг 4: Создайте класс прослушивателя
импорт android.утиль.Бревно; импортировать com.гуглить.гсон.Дсын; импорт java.Ио.IOException; импорт dxswifi_direct.com.wifidirectcommunication.база.модель.просьба.BaseHTTPRequest; импорт okhttp3.Вызов; импорт okhttp3.Тип носителя; импорт okhttp3.OkHttpClient; импорт okhttp3.Обратный звонок; импорт okhttp3.Запрос; импорт okhttp3.Requestbody для; импорт okhttp3.Ответ;
/** * Создано Deepak Sharma на 4/7/16. * @ email : dpsharma.sharma1@gmail.com * Это простой класс java, который поможет вам для HTTP-запроса / ответа, и он будет * бросьте ответ на свою корреспондентскую деятельность. */
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
}
});
}
}
Шаг 5: из действия, которое вы запрашиваете, реализуйте 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;
}
}
}
}