致命异常:doInBackground()中的AsyncTask#4

时间:2013-09-08 16:43:29

标签: android android-asynctask

我正在使用AsyncTask在后台运行数据库查询。运行我的应用程序时出现此错误:

09-08 12:24:04.192: E/AndroidRuntime(882): FATAL EXCEPTION: AsyncTask #4
09-08 12:24:04.192: E/AndroidRuntime(882): java.lang.RuntimeException: An error occured while executing doInBackground()
09-08 12:24:04.192: E/AndroidRuntime(882):  at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-08 12:24:04.192: E/AndroidRuntime(882):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-08 12:24:04.192: E/AndroidRuntime(882):  at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-08 12:24:04.192: E/AndroidRuntime(882):  at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-08 12:24:04.192: E/AndroidRuntime(882):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-08 12:24:04.192: E/AndroidRuntime(882):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-08 12:24:04.192: E/AndroidRuntime(882):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-08 12:24:04.192: E/AndroidRuntime(882):  at java.lang.Thread.run(Thread.java:841)
09-08 12:24:04.192: E/AndroidRuntime(882): Caused by: java.lang.NullPointerException
09-08 12:24:04.192: E/AndroidRuntime(882):  at com.example.loginandregistration.RegisterTask.doInBackground(RegisterTask.java:85)
09-08 12:24:04.192: E/AndroidRuntime(882):  at com.example.loginandregistration.RegisterTask.doInBackground(RegisterTask.java:1)
09-08 12:24:04.192: E/AndroidRuntime(882):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-08 12:24:04.192: E/AndroidRuntime(882):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-08 12:24:04.192: E/AndroidRuntime(882):  ... 4 more

这是我的AsyncTask@RegisterTask.java:

package com.example.loginandregistration;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import library.DatabaseHandler;
import library.JSONParser;
import library.UserFunctions;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;

import android.util.Log;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class RegisterTask extends AsyncTask<String, Void, Integer> {

private ProgressDialog progressDialog;
private RegisterActivity activity;
private int id = -1;
private JSONParser jsonParser;
private static String loginURL = "http://10.0.2.2/android_api/";
private static String registerURL = "http://10.0.2.2/android_api/";
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";
private int responseCode = 0;

/*Constructor that takes parameters passed by LoginFragment and stores them as class- 
 * wide fields so that all methods can access necessary variables. 
 * */
public RegisterTask(RegisterActivity activity, ProgressDialog progressDialog)
{
    this.activity = activity;
    this.progressDialog = progressDialog;
}

/*A necessary but very simple method that launches a ProgressDialog to show the
 * user that a background task is operating (registration).*/
@Override
protected void onPreExecute()
{
    progressDialog.show();
}

/*This method does almost all of the work for the class. It builds a connection to my 
 * server, collects the details from the UI of the user's information, and then tries
 * to register the user with the SQL database. All of the actual HTTP connection work
 * is done in a background library class for security - including the hashing of a
 * password into a 64bit encryption. */
@Override
protected Integer doInBackground(String... arg0) {
    EditText userName = (EditText)activity.findViewById(R.id.registerEmail);
    EditText passwordEdit = (EditText)activity.findViewById(R.id.registerPassword);
    EditText nameEdit = (EditText)activity.findViewById(R.id.registerName);
    String name = nameEdit.getText().toString();
    String email = userName.getText().toString();
    String password = passwordEdit.getText().toString();
    Log.v(email, password);
    UserFunctions userFunction = new UserFunctions();
    JSONObject json = userFunction.registerUser(name, email, password);

    // check for login response
    try {
        if (json.getString(KEY_SUCCESS) != null) {
            //registerErrorMsg.setText("");
            String res = json.getString(KEY_SUCCESS);
            if(Integer.parseInt(res) == 1){
                // user successfully registred
                // Store user details in SQLite Database
                DatabaseHandler db = new DatabaseHandler(activity.getApplicationContext());
                JSONObject json_user = json.getJSONObject("user");

                // Clear all previous data in database
                userFunction.logoutUser(activity.getApplicationContext());
                db.addUser(json_user.getString(KEY_NAME), 
                    json_user.getString(KEY_EMAIL), json.getString(KEY_UID), 
                    json_user.getString(KEY_CREATED_AT));
                //successful registration
                responseCode = 1;
            }else{
                // Error in registration
                responseCode = 0;
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return responseCode;
}

/*This final method concludes the background task. Its responseCode variable is sent from
 * doInBackground, and this method acts based on the code it is sent. If the code is 1, 
 * registration was successful and the main activity notifies the user of succes - the
 * inverse occurs if there is a failure and 0 was sent.*/
@Override
protected void onPostExecute(Integer responseCode)
{
    EditText userName = (EditText)activity.findViewById(R.id.registerEmail);
    EditText passwordEdit = (EditText)activity.findViewById(R.id.registerPassword);
    String s = userName.getText().toString();

    if (responseCode == 1) {
        progressDialog.dismiss();
        activity.registerReport(responseCode);
        userName.setText("");
        passwordEdit.setText("");   
    }
    if (responseCode == 0) {
        progressDialog.dismiss();
        activity.registerReport(responseCode);  
    }
}
}

我的数据库是使用XAMPP和apache在PHPMyAdmin上设置的。我没有抓到的错误是什么?谢谢!

注意:将第85行更改为if(json!= null&amp;&amp; json.getString(KEY_SUCCESS)!= null)

我现在收到此错误:

09-08 12:54:08.202: E/JSON Parser(974): Error parsing data org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONObject
09-08 12:54:07.522: V/err(974): <br />
09-08 12:54:07.952: V/err(974): <b>Parse error</b>:  syntax error, unexpected '@' in <b>C:\xampp\htdocs\android_api\include\DB_Connect.php</b> on line <b>19</b><br />

我的JSONParser.java是这样的:

public class JSONParser {

static InputStream is = null;
static JSONObject jObj = null;
static JSONObject[] jsonArray = null;
static String json = "";

// constructor
public JSONParser() {

}


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

    // Making HTTP request
try {
        // 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();

    } 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");
            Log.v("err", line);

        }
        is.close();
        json = sb.toString();
        //this is the error

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

}

}

进一步编辑:更改了DB_Connect.php中的第19行,但现在出现错误:

09-08 13:01:57.143: V/err(974): <br />
09-08 13:01:57.782: V/err(974): <b>Notice</b>:  Use of undefined constant localhost - assumed 'localhost' in <b>C:\xampp\htdocs\android_api\include\DB_Connect.php</b> on line <b>19</b><br />
09-08 13:01:57.782: V/err(974): <br />
09-08 13:01:58.235: V/err(974): <b>Notice</b>:  Use of undefined constant root - assumed 'root' in <b>C:\xampp\htdocs\android_api\include\DB_Connect.php</b> on line <b>19</b><br />
09-08 13:01:58.242: V/err(974): <br />
09-08 13:01:58.882: V/err(974): <b>Notice</b>:  Use of undefined constant android_api - assumed 'android_api' in <b>C:\xampp\htdocs\android_api\include\DB_Connect.php</b> on line <b>21</b><br />
09-08 13:01:59.502: V/err(974): {"tag":"register","success":1,"error":0,"uid":"522cad85884042.26767614","user":{"name":"abc","email":"abc@gmail.com","created_at":"2013-09-08 11:01:57","updated_at":null}}

它仍然说它注册了我的用户,但我怎么能摆脱这些错误?这是我的DB_Connect.php:

<?php

class DB_Connect {

// constructor
function __construct() {

}

// destructor
function __destruct() {
    // $this->close();
}

// Connecting to database
public function connect() {
    require_once 'config.php';
    // connecting to mysql
    $con = mysql_connect(localhost, root, "");
    // selecting database
    mysql_select_db(android_api);

    // return database handler
    return $con;
}

// Closing database connection
public function close() {
    mysql_close();
}

}

?>

编辑:添加了userFunction(已请求):

userFunction.java:

package library;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;

public class UserFunctions {

private JSONParser jsonParser;

private static String loginURL = "http://10.0.2.2/android_api/";
private static String registerURL = "http://10.0.2.2/android_api/"; 

private static String login_tag = "login";
private static String register_tag = "register";
private static String question_tag = "question";

// constructor
public UserFunctions(){
    jsonParser = new JSONParser();
}

 //login with user provided email/pass
public JSONObject loginUser(String email, String password){
    // Building Parameters
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", login_tag));
    params.add(new BasicNameValuePair("email", email));
    params.add(new BasicNameValuePair("password", password));
    //Log.v("userfunctions", "loginuser");
    JSONObject json = jsonParser.getJSONFromUrl(loginURL, params);
    // return json
    return json;
}

//register a new user with name/email/pass
public JSONObject registerUser(String name, String email, String password){
    // Building Parameters
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", register_tag));
    params.add(new BasicNameValuePair("name", name));
    params.add(new BasicNameValuePair("email", email));
    params.add(new BasicNameValuePair("password", password));

    // getting JSON Object
    JSONObject json = jsonParser.getJSONFromUrl(registerURL, params);
    // return json
    return json;
}

//determine if the user is logged in
public boolean isUserLoggedIn(Context context){
    DatabaseHandler db = new DatabaseHandler(context);
    int count = db.getRowCount();
    if(count > 0){
        // user logged in
        return true;
    }
    return false;
}

//logout the user
public boolean logoutUser(Context context){
    DatabaseHandler db = new DatabaseHandler(context);
    db.resetTables();
    return true;
}
}

2 个答案:

答案 0 :(得分:2)

您收到NullPointerException,因为您尝试从doInBackground()访问UI线程,而是在onPreExecute()内执行此操作。

答案 1 :(得分:0)

实际上你在json中得到了空值

      userFunction.registerUser(name, email, password);

可能是这个函数没有返回正确的值,请检查