-1

I was using okhttp to create a network util, it successfully get the request ,loggging the return data. However, if I try to parse the return string as json , it throw the NetworkOnMainThreadException.

The HttpUtil Class

public class HttpUtil {

    private OkHttpClient client;
    private Request.Builder builder;

    public void get(String url, HttpCallback cb) {
        call("GET", url, cb);
    }

    public void post(String url, HttpCallback cb) {
        call("POST", url, cb);
    }

    private void call(String method, String url, final HttpCallback cb) {
        client = new OkHttpClient();

        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new Callback() {
            Handler mainHandler = new Handler(Looper.getMainLooper());

            @Override
            public void onFailure(Request request,final IOException e) {
                mainHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        cb.onFailure(null, e);
                    }
                });

            }

            @Override
            public void onResponse(final Response response) throws IOException {
                mainHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        if (!response.isSuccessful()) {
                            cb.onFailure(response, null);
                            return;
                        }
                        cb.onSuccess(response);
                    }
                });

            }
        });
    }


    public interface HttpCallback {

        /**
         * called when the server response was not 2xx or when an exception was thrown in the process
         *
         * @param response  - in case of server error (4xx, 5xx) this contains the server response
         *                  in case of IO exception this is null
         * @param throwable - contains the exception. in case of server error (4xx, 5xx) this is null
         */
        public void onFailure(Response response, Throwable throwable);

        /**
         * contains the server response
         *
         * @param response
         */
        public void onSuccess(Response response);
    }

}

And the fragment that call the util

new HttpUtil().get(Constant.get_cat_list, new HttpUtil.HttpCallback() {
        @Override
        public void onFailure(Response response, Throwable throwable) {
            Toast.makeText(getActivity(), getResources().getString(R.string.network_err), Toast.LENGTH_LONG).show();
        }

        @Override
        public void onSuccess(Response response) {
            items = new ArrayList<Item>();

            String data = null;
            try {

                /* !!!!!!!!!!!!!!!Below line fail!!!!!!!!!!!!!!!!!*/

                data = response.body().string();
                JSONArray json_array = new JSONArray(data);

                for (int i = 0; i < json_array.length(); i++) {
                    JSONObject object = json_array.getJSONObject(i);
                    items.add(new Item(object.getString("title_tw"), object.getString("image_url")));
                }

            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }

            gridView.setAdapter(new MyAdapter(getActivity()));
        }
    });

    return v;
}

The exception throw at data = response.body().string(); in the fragment when receive the callback. I wonder is that means I also need the async task for parse JSON? (As I remember in pervious project it doesn't need to)

Thanks a lot for helping.

user782104
  • 13,233
  • 55
  • 172
  • 312

1 Answers1

1

NetworkOnMainThreadException will be thrown when you try to run Network operation on MainThread. Using AsyncTask instead.

Kingcesc
  • 84
  • 1
  • 6