Search code examples
javaandroidillegalstateexception

Android: IllegalStateException thrown


In the LoginActivity.java class, when a user clicks a register button, then the code sets the login session true and then switches the activity from LoginActivity to MainActivity. Here's the login code snippet.

            case(R.id.login):
                String email = etEmail.getText().toString();
                String password = etPassword.getText().toString();

                if(email.trim().length() > 0 && password.trim().length() > 0) {
                    loginManager.checkLogin(email, password);
                    pDialog.setMessage("Logging in..");
                    showDialog();
                    session.setLogin(true);

                    if(loginManager.isLoginSuccessful()) {
                        hideDialog();
                        Toast.makeText(this, getResources().getString(R.string.welcome_msg), Toast.LENGTH_LONG).show();
                        Intent intent = new Intent(this, MainActivity.class);
                        startActivity(intent);
                        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
                        finish();
                    } else {
                        Toast.makeText(this, loginManager.getErrorMessage(), Toast.LENGTH_LONG).show();
                    }

                } else if(email.trim().length() < 1) {
                    Toast.makeText(this, "Please enter the email", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "Please enter the password", Toast.LENGTH_SHORT).show();
                }
                break;

And here's the LoginManager.java file that deals with the login process. I used OkHttp for the HTTP library.

public class LoginManager {
    private final String TAG_LOGIN = LoginManager.class.getSimpleName();
    private OkHttpClient client = new OkHttpClient();
    private final String loginURL = URL.getInstance().getUrlLogin();
    private Request request = new Request.Builder().url(loginURL).build();

    private static JSONObject jsonObject;
    private boolean error;

    public void checkLogin(final String email, final String password) {

        client.newCall(request).enqueue(new Callback() {

            // onFailure is called when the request could not be executed due to cancellation, a connectivity problem or timeout.
            @Override
            public void onFailure(Request request, IOException e) {

            }

            // onResponse is called when the HTTP response was successfully returned by the remote server.
            // using POST request for login
            @Override
            public void onResponse(Response response) throws IOException {
                Log.d(TAG_LOGIN, "Login response: " + response.body().string());
                RequestBody body = new FormEncodingBuilder()
                        .add("tag", "login")
                        .add("email", email)
                        .add("password", password)
                        .build();
                Request request = new Request.Builder().url(loginURL).post(body).build();
                client.newCall(request).execute();

                try {
                    jsonObject = new JSONObject(response.body().string());
                    error = jsonObject.getBoolean("error");
                } catch(JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public boolean isLoginSuccessful() {
        if(error) {
            return false;
        }
        return true;
    }

    public String getErrorMessage() {
        String errorMessage = null;
        try {
            jsonObject.getString("error_msg");
        } catch(JSONException e) {
            e.printStackTrace();
        }

        return errorMessage;
    }
}

When I run the application, it shows the welcome toast message and suddenly quits with the following error log.

java.lang.IllegalStateException: closed
            at com.squareup.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:454)
            at okio.Buffer.writeAll(Buffer.java:574)
            at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:87)
            at com.squareup.okhttp.ResponseBody.bytes(ResponseBody.java:56)
            at com.squareup.okhttp.ResponseBody.string(ResponseBody.java:82)
            at com.marshall.thequizshow.application.http.LoginManager$1.onResponse(LoginManager.java:51)
            at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:150)
            at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)

So, I must be having a bug with the try-catch phrase under the onResponse method in the LoginManager.java file.

try {
                    jsonObject = new JSONObject(response.body().string());
                    error = jsonObject.getBoolean("error");
                } catch(JSONException e) {
                    e.printStackTrace();
                }

I would like to ask you how I should fix the code so that it no longer catches the IllegalStateException.

Thank you in advance.


Solution

  • As a general answer, YES: The proper way to avoid a RuntimeException is to fix the code: They should not be catched by program, under normal circunstances.

    Now, let's see your case... The IllegalStateException arises because the HttpConnection seems to be closed when trying to use it. Could it be because you are calling twice the method response.body()?