0

I have made a database using wampserver for login process and created proper php files and i can login successfully through my browser . But i made an App and connected database using JSONParser now my App crashes whenever i try to login . This is what logcat screen shows ..

06-29 11:51:37.044  15586-15889/com.zaid.sling.mysqltest E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)

           .....

     Caused by: java.lang.NullPointerException
            at com.zaid.sling.mysqltest.Login$AttemptLogin.doInBackground(Login.java:125)

This is my JSONParser.java

 public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // constructor
    public JSONParser() {

    }

    // function get json from url
    // by making HTTP POST or GET mehtod
    public JSONObject makeHttpRequest(String url, String method,
                                      List<NameValuePair> params) {

        // Making HTTP request
        try {

            // check for request method
            if(method == "POST"){
                // request method is POST
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);
                httpPost.setEntity(new UrlEncodedFormEntity(params));

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            }else if(method == "GET"){
                // request method is GET
                DefaultHttpClient httpClient = new DefaultHttpClient();
                String paramString = URLEncodedUtils.format(params, "utf-8");
                url += "?" + paramString;
                HttpGet httpGet = new HttpGet(url);

                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;

    }
 }

This is my Login.java

public class Login extends Activity implements OnClickListener{

    private EditText user, pass;
    private Button mSubmit, mRegister;

    // Progress Dialog
    private ProgressDialog pDialog;

    // JSON parser class
    JSONParser jsonParser = new JSONParser();

    //php login script location:

    private static final String LOGIN_URL "http://10.0.2.2/webservice/login.php";


    //JSON element ids from repsonse of php script:
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_MESSAGE = "message";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //setup input fields
        user = (EditText)findViewById(R.id.username);
        pass = (EditText)findViewById(R.id.password);

        //setup buttons
        mSubmit = (Button)findViewById(R.id.login);
        mRegister = (Button)findViewById(R.id.register);

        //register listeners
        mSubmit.setOnClickListener(this);
        mRegister.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
            case R.id.login:
                new AttemptLogin().execute();
                break;
            case R.id.register:
                Intent i = new Intent(this, Register.class);
                startActivity(i);
                break;

            default:
                break;
        }
    }

    class AttemptLogin extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         * */
        boolean failure = false;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(Login.this);
            pDialog.setMessage("Attempting login...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        @Override
        protected String doInBackground(String... args) {
            // TODO Auto-generated method stub
            // Check for success tag
            int success;
            String username = user.getText().toString();
            String password = pass.getText().toString();
            try {
                // Building Parameters
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("username", username));
                params.add(new BasicNameValuePair("password", password));

                Log.d("request!", "starting");
                // getting product details by making HTTP request
                JSONObject json = jsonParser.makeHttpRequest(
                        LOGIN_URL, "POST", params);

                // check your log for json response
                Log.d("Login attempt", json.toString());

                // json success tag
                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    Log.d("Login Successful!", json.toString());
                    Intent i = new Intent(Login.this, ReadComment.class);
                    finish();
                    startActivity(i);
                    return json.getString(TAG_MESSAGE);
                }else{
                    Log.d("Login Failure!", json.getString(TAG_MESSAGE));
                    return json.getString(TAG_MESSAGE);

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

            return null;

        }
        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // dismiss the dialog once product deleted
            pDialog.dismiss();
            if (file_url != null){
                Toast.makeText(Login.this, file_url, Toast.LENGTH_LONG).show();
            }
        }
    }
}

In my php files there is html form too and the login process is working fine using a browser

This is the logcat after updating above code with @Daniel Nugent s code

06-30 12:19:30.579  26905-26960/com.zaid.sling.mysqltest E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            ..........
            at java.lang.Thread.run(Thread.java:856)
     Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
            at com.zaid.sling.mysqltest.Login$AttemptLogin.doInBackground(Login.java:107)

plz help thanks in advance

ZaidRehman
  • 1,631
  • 2
  • 19
  • 30

3 Answers3

2

There are multiple problems in your code. First, you are calling finish() inside your doInBackground() method, which probably caused the leaked window. You should not be finishing the Activity while an AsyncTask is running, regardless of whether or not you have a ProgressDialog showing.

You're also using the deprecated DefaultHttpClient, which won't work in Android 5.0 and later.

I just got a solution working and tested with a PHP page I have on a server.

First, here's a modified JSONParser class, which uses HttpURLConnection:

import android.util.Log;
import org.apache.http.NameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/**
 * Created by daniel on 6/29/15.
 */
public class JSONParser {

    HttpURLConnection conn;
    DataOutputStream wr;
    StringBuilder result = new StringBuilder();
    URL urlObj;
    static JSONObject jObj = null;
    static String json = "";

    public JSONParser() {

    }

    public JSONObject makeHttpRequest(String url,
                                      List<NameValuePair> params) {

        try {
            urlObj = new URL(url);

            conn = (HttpURLConnection) urlObj.openConnection();

            conn.setDoOutput(true); //moved here

            conn.setRequestMethod("POST");
            conn.connect();

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


        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);

        StringBuilder sbCert = new StringBuilder();
        for (int i = 0; i < params.size(); i++){
            if (i != 0){
                sbCert.append("&");
            }
            NameValuePair nvp = params.get(i);
            sbCert.append(nvp.getName()).append("=").append(nvp.getValue());
        }

        String cert=sbCert.toString();


        try {
            wr = new DataOutputStream(conn.getOutputStream());
            wr.writeBytes(cert);
            wr.flush();
            wr.close();

            InputStream in = new BufferedInputStream(conn.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            Log.d("JSON Parser", "result: " + result.toString());

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


        conn.disconnect();


        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(result.toString());
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON Object
        return jObj;

    }
}

Next, here's a modified version of your AsyncTask:

class AttemptLogin extends AsyncTask<String, String, String> {

    boolean failure;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Attempting login...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... args) {

        int success;
        String username = args[0];
        String password = args[1];


        try {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("name", username));
            params.add(new BasicNameValuePair("password", password));

            Log.d("request!", "starting");
            // getting product details by making HTTP request
            JSONObject json = jsonParser.makeHttpRequest(
                    LOGIN_URL, params);

            // check your log for json response
            Log.d("Login attempt", json.toString());

            // json success tag
            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                failure = false;
                Log.d("Login Successful!", json.toString());

            }else{
                failure = true;
                Log.d("Login Failure!", json.getString(TAG_MESSAGE));
            }
            return json.getString(TAG_MESSAGE);

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

        return null;

    }

    protected void onPostExecute(String file_url) {
        // dismiss the dialog once product deleted
        pDialog.dismiss();
        if (file_url != null){
            Toast.makeText(MainActivity.this, file_url, Toast.LENGTH_LONG).show();
        }


        if (failure == false) {
            Intent i = new Intent(Login.this, ReadComment.class);
            //finish();
            Login.this.startActivity(i);
        }

    }
}

And call it like this:

new AttemptLogin().execute( user.getText().toString(), pass.getText().toString());

Of course also make sure you have the INTERNET permission in your AndroidManifest.xml:

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

Logs from running the code with the PHP page on my server:

D/JSON Parser﹕ result: {"success":1,"message":"Message successfully created."}
D/Login attempt﹕ {"message":"Message successfully created.","success":1}
D/Login Successful!﹕ {"message":"Message successfully created.","success":1}
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
  • @ZaidQureshi Append your updated logs to the end of your question as an edit. I'll take a look. – Daniel Nugent Jun 30 '15 at 06:44
  • I uploaded the current logcat . please help – ZaidRehman Jun 30 '15 at 06:56
  • is there any problem with my following line in Login.java ?- new AttemptLogin().execute(); Should i use some parameters to in execute ? – ZaidRehman Jul 01 '15 at 04:47
  • @ZaidQureshi Ahh, yes. Take a look at how I call it in the answer: `new AttemptLogin().execute( user.getText().toString(), pass.getText().toString());` This is because I moved the username and password to be passed in through the varargs parameter in `doInBackground()`. That would explain the ArrayIndexOutOfBoundsException! – Daniel Nugent Jul 01 '15 at 04:53
0

From the stacktrace, it seems that the exception is occurring at:

    06-29 11:51:40.064  15586-15586/com.zaid.sling.mysqltest E/WindowManager﹕ Activity com.zaid.sling.mysqltest.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41d684b0 that was originally added here
        android.view.WindowLeaked: Activity com.zaid.sling.mysqltest.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41d684b0 that was originally added here
        ...
        at android.app.Dialog.show(Dialog.java:277)
        at com.zaid.sling.mysqltest.Login$AttemptLogin.onPreExecute(Login.java:103)
        at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
        at android.os.AsyncTask.execute(AsyncTask.java:534)
        at com.zaid.sling.mysqltest.Login.onClick(Login.java:77)
        ...

And the exception that is occurring is a android.view.WindowLeaked exception.

This happens when you try to display a dialog after an Activity has exited.

Refer to this answer and comments (especially Bobby's) for details.

Community
  • 1
  • 1
Binaek Sarkar
  • 617
  • 8
  • 21
0

please read the information below:

  1. First problem is you are calling finish() before dismiss the dialog. Now if this will be solved then.
  2. You are trying to update or handle the UI in doInBackground method which is not possible. To solve the problem you have to update UI in post execute or Use runUiThread() method to update UI in Backround process.

Updated Code:

      class AttemptLogin extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    boolean failure = false;
    int success;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(Login.this);
        pDialog.setMessage("Attempting login...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub
        // Check for success tag

        String username = user.getText().toString();
        String password = pass.getText().toString();
        try {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("username", username));
            params.add(new BasicNameValuePair("password", password));

            Log.d("request!", "starting");
            // getting product details by making HTTP request
            JSONObject json = jsonParser.makeHttpRequest(
                    LOGIN_URL, "POST", params);

            // check your log for json response
            Log.d("Login attempt", json.toString());

            // json success tag
            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                Log.d("Login Successful!", json.toString());

                return json.getString(TAG_MESSAGE);
            }else{
                Log.d("Login Failure!", json.getString(TAG_MESSAGE));
                return json.getString(TAG_MESSAGE);

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

        return null;

    }
    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once product deleted
        pDialog.dismiss();

         if (success == 1) {
                Log.d("Login Successful!", json.toString());
              Intent i = new Intent(Login.this, ReadComment.class);
               startActivity(i);
               finish();
            }else{
                Log.d("Login Failure!", "your Message");


            }
        if (file_url != null){
            Toast.makeText(Login.this, file_url, Toast.LENGTH_LONG).show();
        }

    }

}
Balvinder Singh
  • 580
  • 6
  • 19
  • can you please provide me the changes do i need to do in the code. That is should i write finish() before or after return statement ? and what exactly are changes required to solve the second issue and thanks in advance – ZaidRehman Jun 30 '15 at 05:58
  • I replaced the whole AttempLogin class and the problem remains as it is and logcat also showing same errors – ZaidRehman Jun 30 '15 at 06:39