我正在使用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;
}
}
答案 0 :(得分:2)
您收到NullPointerException
,因为您尝试从doInBackground()
访问UI线程,而是在onPreExecute()
内执行此操作。
答案 1 :(得分:0)
实际上你在json中得到了空值
userFunction.registerUser(name, email, password);
可能是这个函数没有返回正确的值,请检查