Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android/OkHttp - client.newCall(request).execute() always return exception

I have to make an android application project. At first, I tried to use HttpURLConnection but it didn't work. So after a discussion with a friend, I tried to use OkHttp. I all time got an exception for "responses = client.newCall(request).execute();". After long hours of searching, I just try this code, which is the tutorial of "https://github.com/square/okhttp/wiki/Recipes" And..... It doesn't work too ! My question is, what is really happening? I'm currently developping a 4.0.3 application under Android Studio 1.5.1. I also add the two following dependencies:

// DEPENDENCIES
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

// Class Http
public static String run(String url) throws IOException {
    try {
        OkHttpClient client = new OkHttpClient();
        RequestBody formBody = new FormEncodingBuilder()
                .add("login", "Mr. X")
                .add("password", "********")
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
        Response responses = null;

        try {
            Log.d("DEBUGG ", "----------------------------------");
            responses = client.newCall(request).execute();
            Log.d("DEBUGG ", "----------------------------------");
            return (responses.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
        String jsonData = responses.body().string();
        JSONObject Jobject = new JSONObject(jsonData);
        JSONArray Jarray = Jobject.getJSONArray("employees");

        for (int i = 0; i < Jarray.length(); i++) {
            JSONObject object = Jarray.getJSONObject(i);
        }
    } catch (JSONException e) {

    }
    return null;
}

// MainActivity
private TextView textView;
private Button button;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = (TextView)findViewById(R.id.textViewJSon);
    button = (Button)findViewById(R.id.Hit);

    textView.setText("Hello !");

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                textView.setText(Http.run("https://epitech-api.herokuapp.com/login"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

}
like image 219
E.J. Avatar asked Sep 13 '25 19:09

E.J.


2 Answers

{ ANSWER } I finally tried to use multi-threading programming like said Selvin and it works well So the solution is to open another thread

public static int responseCode = 0;
public static String responseString = "";

public static Thread login = new Thread(new Runnable() {
    private OkHttpClient client = new OkHttpClient();
    private String url = "https://epitech-api.herokuapp.com/login";
    private User user = User.getUser();

    public void run() {
        try {
            // Build the request
            RequestBody formBody = new FormEncodingBuilder()
                .add("login", user._login)
                .add("password", user._password)
                .build();
            Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
            Response responses = null;

            // Reset the response code
            responseCode = 0;

            // Make the request
            responses = client.newCall(request).execute();

            if ((responseCode = responses.code()) == 200) {
                // Get response
                String jsonData = responses.body().string();

                // Transform reponse to JSon Object
                JSONObject json = new JSONObject(jsonData);

                // Use the JSon Object
                user._token = json.getString("token");
            }

        } catch (IOException e) {
            responseString = e.toString();
        } catch (JSONException e) {
            responseString = e.toString();
      }
   }
});
like image 165
E.J. Avatar answered Sep 16 '25 09:09

E.J.


Most probably, since Honeycomb, network operation in main thread is restricted. So, calling the execute() method is useful when you are already in background thread. But if you are in the main thread then enqueue() will be helpful as it will process the network request in background thread and return the response in main thread. In that case, you just need to pass a callback to get the response.

As you mentioned, using Okhttp is a suggestion from your friend. I also want to recommend you to use Retrofit. It will make your code nicer and maintainable and also handle the threading on behalf of you. Under the hood, it uses Okhttp. More importantly, since version 2.6.0 you can feel the synchronous experience with the help of Coroutines.

like image 24
Roaim Avatar answered Sep 16 '25 11:09

Roaim