2015-12-08 3 views
2

Я использую OKHttp выполнить Post запрос на сервер, как следует:Выполняют OkHttp сетевых действий в фоновом потоке

public class NetworkManager { 
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); 
    OkHttpClient client = new OkHttpClient(); 

    String post(String url, JSONObject json) throws IOException { 
     try { 
      JSONArray array = json.getJSONArray("d"); 
      RequestBody body = new FormEncodingBuilder() 
        .add("m", json.getString("m")) 
        .add("d", array.toString()) 
        .build(); 
      Request request = new Request.Builder() 
        .url(url) 
        .post(body) 
        .build(); 
      Response response = client.newCall(request).execute(); 
      return response.body().string(); 
     } catch (JSONException jsone) { 
      return "ERROR: " + jsone.getMessage(); 
     } 
    } 
} 

и называют его:

NetworkManager manager = new NetworkManager(); 
String response = manager.post("http://www.example.com/api/", jsonObject); 

Когда я пытаюсь запустить приложение , он запрашивает ошибку в LogCat:

android.os.NetworkOnMainThreadException
на android.os.StrictMode $ AndroidBlockGuardPolicy.onNetwork (StrictMode.java:1273)

Со ссылкой на другие вопросы в SO, я добавил это переопределение политики:

if (android.os.Build.VERSION.SDK_INT > 9) 
{ 
     StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
     StrictMode.setThreadPolicy(policy); 
} 

Но я подумайте, что это нездорово, и я хотел бы поместить действия NetworkManager на фон. Как я могу это сделать?

ответ

5

Поскольку OkHttp поддерживает асинхронный путь тоже, так что ИМО вы можете обратиться к следующим GET образцу запроса, а затем подать заявку на ваш запрос на POST:

 OkHttpClient client = new OkHttpClient(); 
     // GET request 
     Request request = new Request.Builder() 
       .url("http://google.com") 
       .build(); 
     client.newCall(request).enqueue(new Callback() { 
      @Override 
      public void onFailure(Request request, IOException e) { 
       Log.e(LOG_TAG, e.toString()); 
      } 
      @Override 
      public void onResponse(Response response) throws IOException { 
       Log.w(LOG_TAG, response.body().string()); 
       Log.i(LOG_TAG, response.toString()); 
      } 
     }); 

Надеется, что это помогает!

+1

Порекомендуйте асинхронную опцию OkHttp. – novak

+0

Выглядит многообещающе. Как сообщить основному классу, когда ответ готов? Моя текущая логика является синхронной и напрямую возвращает строку ответа, затем основной класс анализирует ответ на дальнейшие действия. – Raptor

+1

Как вы видите, внутри 'onResponse' вы это сделаете, если вы хотите обновить интерфейс или отобразить Toast, вам также понадобится' mHandler = new Handler (Looper.getMainLooper()); '. Если запрос внутри другого класса (например, Utils.java), я думаю, вы должны использовать интерфейс прослушивателя – BNK

Смежные вопросы