繁体   English   中英

每当我尝试使用JSONParser登录时,Android App都会崩溃,但我可以使用浏览器成功登录

[英]Android App crashes whenever i try to login using JSONParser but i can sucessfully login with my browser

我已经使用wampserver建立了数据库进行登录,并创建了适当的php文件,并且可以通过浏览器成功登录。 但是我使用JSONParser创建了一个应用程序并连接了数据库,现在每当我尝试登录时,我的应用程序就会崩溃。 这是logcat屏幕显示的内容。

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)

这是我的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;

    }
 }

这是我的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();
            }
        }
    }
}

在我的php文件中也有html表单,并且使用浏览器可以正常进行登录过程

这是用@Daniel Nugent的代码更新以上代码后的日志猫

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)

请帮助提前感谢

您的代码中存在多个问题。 首先,您在doInBackground()方法中调用finish() ,这可能导致窗口泄漏。 不管您是否显示ProgressDialog,都不应在AsyncTask运行时完成Activity。

您还使用了不推荐使用的DefaultHttpClient ,它将在Android 5.0及更高版本中不起作用。

我刚刚有了一个可以在服务器上使用的PHP页面工作并经过测试的解决方案。

首先,这是一个修改后的JSONParser类,它使用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;

    }
}

接下来,这是您的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);
        }

    }
}

并这样称呼它:

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

当然,还要确保您在AndroidManifest.xml中具有INTERNET权限:

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

通过服务器上的PHP页面运行代码的日志:

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}

从堆栈跟踪看来,异常发生在:

    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)
        ...

并且发生的异常是android.view.WindowLeaked异常。

当您尝试退出活动后显示对话框时,会发生这种情况。

有关详细信息,请参考答案和评论(尤其是Bobby的评论)。

请阅读以下信息:

  1. 第一个问题是您在退出对话框之前正在调用finish()。 现在,如果这将解决。
  2. 您正在尝试使用doInBackground方法更新或处理UI,这是不可能的。 要解决该问题,您必须在执行后更新UI或在Backround进程中使用runUiThread()方法更新UI。

更新的代码:

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

    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM