2015-01-25 13 views
20

Tôi muốn sử dụng thư viện OkHttp để kết nối mạng trong Android. tôi bắt đầu với đơn giản bài ví dụ như được viết trong trang web của họ:Thư viện OkHttp - NetworkOnMainThreadException trên bài đăng đơn giản

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

Với cuộc gọi này:

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

Cuộc gọi này kết thúc với NetworkOnMainThreadException.
Tôi có thể kết thúc cuộc gọi với AsyncTask, nhưng theo như tôi hiểu từ các ví dụ, thư viện OkHttp nên đã thực hiện việc đó .. Tôi có làm gì sai không?

+0

thể trùng lặp của [android.os.NetworkOnMainThreadException] (http://stackoverflow.com/questions/6343166/ android-os-networkonmainthreadexception) Bạn có nghĩ đến việc tìm kiếm trước không? – Simon

+3

Nó không liên quan gì đến điều đó .. Đọc lại câu hỏi. Đặc biệt là các bộ phận in đậm. Bạn có nghĩ về việc đọc trước không? –

+0

Tôi đã đọc câu hỏi và mọi thứ liên quan đến điều đó. Bạn đang dong mạng IO trên chủ đề chính. Nó không quan trọng bạn nghĩ gì ** thư viện đang làm, chỉ có một nguyên nhân của ngoại lệ này. – Simon

Trả lời

39

Bạn nên sử dụng phương pháp không đồng bộ của 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; 
} 

Và sau đó trả lời của bạn sẽ được xử lý trong 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 
    } 
    } 
}); 

Hoặc 3.x OkHttp:

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

Hãy xem công thức nấu ăn của họ để biết thêm ví dụ: https://github.com/square/okhttp/wiki/Recipes

+2

Bạn nên xóa 'Phản hồi phản hồi' vì' .queque (gọi lại) 'trả về không có gì + nên có' void post ('thay thế của 'String post (' –

4

Theo tài liệu OkHttp: Nó hỗ trợ cả cuộc gọi chặn đồng bộ và cuộc gọi không đồng bộ với cuộc gọi lại. dụ của bạn là về chủ đề chính và Android kể từ phiên bản 3.0 ném ngoại lệ là nếu bạn cố gắng làm các cuộc gọi mạng trên chủ đề chính

lựa chọn tốt hơn là sử dụng nó cùng với trang bị thêm và Gson: http://square.github.io/retrofit/ https://code.google.com/p/google-gson/

đây là các ví dụ: http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-android/ http://heriman.net/?p=5

+0

Có ai biết nếu có thể thực hiện "PATCH" bằng OkHttp không? Tôi đã nhìn và tôi không thể tìm thấy bất kỳ ví dụ. Bất kỳ ý tưởng và đề xuất nào đều được đánh giá cao. – ito

+0

Nó phải giống như sử dụng bài(). Định nghĩa là trong lớp Yêu cầu: Patch công cộng (RequestBody body) { phương thức trả lại ("PATCH", body); } – kjurkovic

+0

cách xử lý các phản hồi khác nhau trong trang bị thêm? –

0

Nếu bạn làm theo các bước sau để triển khai OKHTTP, thì chắc chắn bạn sẽ gọi nhiều API trên nhiều màn hình bằng cách áp dụng chỉ có hai dòng mã

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

Bước 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(); 

Bước 2: Tạo một lớp yêu cầu

/** * Tạo bởi Deepak Sharma vào ngày 4/7/16. * Đây là lớp yêu cầu HTTP có các tham số cơ bản. * Nếu bạn muốn thêm một số thông số khác, hãy tạo một lớp con của lớp đó * và thêm với lớp con của bạn. Không sửa đổi lớp này. */

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

bước 4: Tạo một lớp người nghe

nhập khẩu android.util.Log; nhập com.google.gson.Gson; nhập java.io.IOException; nhập dxswifi_direct.com.wifidirectcommunication.base.model.request.BaseHTTPRequest; nhập okhttp3.Call; nhập okhttp3.MediaType; nhập okhttp3.OkHttpClient; nhập okhttp3.Callback; nhập okhttp3.Request; nhập okhttp3.RequestBody; nhập okhttp3.Response;

/** * Được tạo bởi Deepak Sharma vào ngày 4/7/16. * @email: [email protected] * Đây là lớp java đơn giản sẽ giúp bạn yêu cầu/trả lời HTTP và nó sẽ * gửi phản hồi đến hoạt động tương ứng của bạn. */

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

bước 5: Từ hoạt động bạn yêu cầu, thực hiện nghe

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; 

} 

} 
} 

} 
Các vấn đề liên quan