我是Android编程的新手,我无法确定哪个触发了错误。有人可以向我解释错误以及如何摆脱错误吗?
我有这个错误:
09-16 10:09:05.529: E/AndroidRuntime(26221): FATAL EXCEPTION: AsyncTask #1
09-16 10:09:05.529: E/AndroidRuntime(26221): java.lang.RuntimeException: An error occured while executing doInBackground()
09-16 10:09:05.529: E/AndroidRuntime(26221): at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-16 10:09:05.529: E/AndroidRuntime(26221): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-16 10:09:05.529: E/AndroidRuntime(26221): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-16 10:09:05.529: E/AndroidRuntime(26221): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-16 10:09:05.529: E/AndroidRuntime(26221): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-16 10:09:05.529: E/AndroidRuntime(26221): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-16 10:09:05.529: E/AndroidRuntime(26221): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-16 10:09:05.529: E/AndroidRuntime(26221): at java.lang.Thread.run(Thread.java:841)
09-16 10:09:05.529: E/AndroidRuntime(26221): Caused by: java.lang.NullPointerException
09-16 10:09:05.529: E/AndroidRuntime(26221): at com.databaseaar.Login_new$AttemptLogin.doInBackground(Login_new.java:82)
09-16 10:09:05.529: E/AndroidRuntime(26221): at com.databaseaar.Login_new$AttemptLogin.doInBackground(Login_new.java:1)
09-16 10:09:05.529: E/AndroidRuntime(26221): at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-16 10:09:05.529: E/AndroidRuntime(26221): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-16 10:09:05.529: E/AndroidRuntime(26221): ... 4 more
09-16 10:09:06.459: E/WindowManager(26221): Activity com.databaseaar.Login_new has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{42c25fb0 V.E..... R......D 0,0-684,192} that was originally added here
09-16 10:09:06.459: E/WindowManager(26221): android.view.WindowLeaked: Activity com.databaseaar.Login_new has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{42c25fb0 V.E..... R......D 0,0-684,192} that was originally added here
09-16 10:09:06.459: E/WindowManager(26221): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:452)
09-16 10:09:06.459: E/WindowManager(26221): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:258)
09-16 10:09:06.459: E/WindowManager(26221): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:73)
09-16 10:09:06.459: E/WindowManager(26221): at android.app.Dialog.show(Dialog.java:287)
09-16 10:09:06.459: E/WindowManager(26221): at com.databaseaar.Login_new$AttemptLogin.onPreExecute(Login_new.java:66)
09-16 10:09:06.459: E/WindowManager(26221): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
09-16 10:09:06.459: E/WindowManager(26221): at android.os.AsyncTask.execute(AsyncTask.java:534)
09-16 10:09:06.459: E/WindowManager(26221): at com.databaseaar.Login_new$1.onClick(Login_new.java:49)
09-16 10:09:06.459: E/WindowManager(26221): at android.view.View.performClick(View.java:4475)
09-16 10:09:06.459: E/WindowManager(26221): at android.view.View$PerformClick.run(View.java:18786)
09-16 10:09:06.459: E/WindowManager(26221): at android.os.Handler.handleCallback(Handler.java:730)
09-16 10:09:06.459: E/WindowManager(26221): at android.os.Handler.dispatchMessage(Handler.java:92)
09-16 10:09:06.459: E/WindowManager(26221): at android.os.Looper.loop(Looper.java:137)
09-16 10:09:06.459: E/WindowManager(26221): at android.app.ActivityThread.main(ActivityThread.java:5419)
09-16 10:09:06.459: E/WindowManager(26221): at java.lang.reflect.Method.invokeNative(Native Method)
09-16 10:09:06.459: E/WindowManager(26221): at java.lang.reflect.Method.invoke(Method.java:525)
09-16 10:09:06.459: E/WindowManager(26221): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
09-16 10:09:06.459: E/WindowManager(26221): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
09-16 10:09:06.459: E/WindowManager(26221): at dalvik.system.NativeStart.main(Native Method)
这是我的类Login_new和asynctask:
的代码package com.databaseaar;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Login_new extends Activity implements OnClickListener{
private EditText user, pass;
private Button bLogin;
private ProgressDialog pDialog;
JSONParser jsonParser = new JSONParser();
private static final String LOGIN_URL = "http://xxxx.com/login_new2.php";
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
public static final String KEY_USERNAME ="username";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login2);
user = (EditText)findViewById(R.id.ET_email);
pass = (EditText)findViewById(R.id.ET_password);
bLogin = (Button)findViewById(R.id.btnLogin);
//bLogin.setOnClickListener(Login_new.this);
bLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnLogin:
new AttemptLogin().execute();
default:
break;
}}
});
}
class AttemptLogin extends AsyncTask<String, String, String> {
// public static final String KEY_USERNAME = null;
boolean failure = false;
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Login_new.this);
pDialog.setMessage("Attempting for login...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... args) {
int success;
String username = user.getText().toString();
String password = pass.getText().toString();
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", username));
params.add(new BasicNameValuePair("password", password));
Log.d("request!", "starting");
JSONObject json = jsonParser.makeHttpRequest(LOGIN_URL, "POST", params);
Log.d("Login attempt", json.toString());
// success tag for json
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
Log.d("Successfully Login!", json.toString());
Intent ii = new Intent(Login_new.this,MainActivity.class);
ii.putExtra(KEY_USERNAME, username);
finish();
startActivity(ii);
return json.getString(TAG_MESSAGE);
}else {
return json.getString(TAG_MESSAGE);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String message) {
pDialog.dismiss();
if (message != null){
Toast.makeText(Login_new.this, message, Toast.LENGTH_LONG).show();
}
} }}
PHP代码:
<?php
$con=mysqli_connect("xxxx","xxxx","xxxx","xxxx");
$password=$_POST["password"];
$username=$_POST["username"];
if (!empty($_POST)) {
if (empty($_POST['username']) || empty($_POST['password'])) {
$response["success"] = 0;
$response["message"] = "One or both of the fields are empty .";
}
$query = " SELECT * FROM login WHERE username = '$username'and password='$password'";
$sql1=mysql_query($query);
$row = mysql_fetch_array($sql1);
if (!empty($row)) {
$response["success"] = 1;
$response["message"] = "You have been sucessfully login";
die(json_encode($response));
}else{
$response["success"] = 0;
$response["message"] = "invalid username or password ";
die(json_encode($response));
}}
else{
$response["success"] = 0;
$response["message"] = " One or both of the fields are empty ";
die(json_encode($response));
}
mysql_close();
?>
我的JSON httpRequest
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") {
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 {
jsonObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
return jsonObj;
}
新错误日志cat:
09-08 08:30:14.854: E/Response(2297): <br />
09-08 08:30:14.854: E/Response(2297): <b>Deprecated</b>: mysql_query(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in <b>/home/u747670603/public_html/login_new2.php</b> on line <b>14</b><br />
09-08 08:30:14.854: E/Response(2297): <br />
09-08 08:30:14.854: E/Response(2297): <b>Warning</b>: mysql_query(): Access denied for user 'u747670603'@'10.2.1.25' (using password: NO) in <b>/home/u747670603/public_html/login_new2.php</b> on line <b>14</b><br />
09-08 08:30:14.854: E/Response(2297): <br />
09-08 08:30:14.854: E/Response(2297): <b>Warning</b>: mysql_query(): A link to the server could not be established in <b>/home/u747670603/public_html/login_new2.php</b> on line <b>14</b><br />
09-08 08:30:14.854: E/Response(2297): <br />
09-08 08:30:14.854: E/Response(2297): <b>Warning</b>: mysql_fetch_array() expects parameter 1 to be resource, boolean given in <b>/home/u747670603/public_html/login_new2.php</b> on line <b>15</b><br />
09-08 08:30:14.854: E/Response(2297): {"success":0,"message":"invalid username or password "}
答案 0 :(得分:2)
正如Crash转储所示,它是在onPreExecute()方法中启动的progressDialog的问题。但是在doInBackground()方法中,在某些条件下启动一个活动而不关闭progressDialog。这导致崩溃转储中显示的窗口泄漏。
应该使用doInBackground()来完成网络或其他更难的任务。不应在此方法中调用与UI相关的API,因为此方法在不同的线程上运行(不在主GUI线程上)。因此,我建议您将启动新活动的代码移至onPostExecute()方法,并在启动新活动之前解除progressDialog。
以下是示例代码。
class AttemptLogin extends AsyncTask<String, String, String> {
// public static final String KEY_USERNAME = null;
boolean failure = false;
String username, password;
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Login_new.this);
pDialog.setMessage("Attempting for login...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
username = user.getText().toString();
password = pass.getText().toString();
}
@Override
protected String doInBackground(String... args) {
int success;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", username));
params.add(new BasicNameValuePair("password", password));
Log.d("request!", "starting");
return jsonParser.makeHttpRequest(LOGIN_URL, "POST", params).toString();
} catch (Exception e) {
return null;
}
}
protected void onPostExecute(String message) {
pDialog.dismiss();
if (message != null) {
Toast.makeText(Login_new.this, message, Toast.LENGTH_LONG).show();
try {
JSONObject object = new JSONObject(message);
// success tag for json
int success = object.getInt(TAG_SUCCESS);
if (success == 1) {
Log.d("Successfully Login!", json.toString());
Intent ii = new Intent(Login_new.this,MainActivity.class);
ii.putExtra(KEY_USERNAME, username);
startActivity(ii);
finish();
}
} catch (JSONException 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();
/*
* This line will print the server response.
* Check this response and make changes to the PHP&MySQL accordingly.
* Post this response for further help
*/
Log.e ("Response", json);
} catch (Exception e) {
Log.e("Buffer error", "Error converting result" + e.toString());
}
修改强> 这是一个示例PHP登录脚本(在使用它们之前添加$ username,$ password赋值语句) 的login.php
require_once('Database.php');
$db = new Database();
$stmt = $db->prepare("SELECT * FROM login where username = :username AND password = :password");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();
if ($stmt->rowCount() == 1) {
$result['status'] = 1;
$result['msg'] = "Successfully logged in";
} else {
$result['status'] = 0;
$result['msg'] = "Invalid login credentials";
}
echo json_encode($result);
创建一个新的PHP类文件Database.php在其中添加以下代码。
<?php
class Database extends PDO {
function __construct() {
parent::__construct('mysql:host=localhost;dbname=dbName', 'username', 'password');
parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
}
不要忘记在上面的类构造函数中更改主机名,数据库名称,用户名和密码。
答案 1 :(得分:0)
为什么在开始活动之前完成()?
Intent ii = new Intent(Login_new.this,MainActivity.class);
ii.putExtra(KEY_USERNAME, username);
finish();
startActivity(ii);
您的代码应
Intent ii = new Intent(Login_new.this,MainActivity.class);
ii.putExtra(KEY_USERNAME, username);
startActivity(ii);
并在后期执行中执行完成();
像这样做你的代码。
public class Login_new extends Activity implements OnClickListener{
private EditText user, pass;
private Button bLogin;
private ProgressDialog pDialog;
JSONParser jsonParser = new JSONParser();
private static final String LOGIN_URL = "http://xxxx.com/login_new2.php";
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
public static final String KEY_USERNAME ="username";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login2);
user = (EditText)findViewById(R.id.ET_email);
pass = (EditText)findViewById(R.id.ET_password);
bLogin = (Button)findViewById(R.id.btnLogin);
//bLogin.setOnClickListener(Login_new.this);
bLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnLogin:
new AttemptLogin().execute();
default:
break;
}}
});
}
class AttemptLogin extends AsyncTask<String, String, Boolean> {
// public static final String KEY_USERNAME = null;
boolean failure = false;
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Login_new.this);
pDialog.setMessage("Attempting for login...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... args) {
int success;
String username = user.getText().toString();
String password = pass.getText().toString();
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", username));
params.add(new BasicNameValuePair("password", password));
Log.d("request!", "starting");
JSONObject json = jsonParser.makeHttpRequest(LOGIN_URL, "POST", params);
Log.d("Login attempt", json.toString());
// success tag for json
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
Log.d("Successfully Login!", json.toString());
Intent ii = new Intent(Login_new.this,MainActivity.class);
ii.putExtra(KEY_USERNAME, username);
startActivity(ii);
failure = false;
return json.getString(TAG_MESSAGE);
}else {
return json.getString(TAG_MESSAGE);
}
} catch (JSONException e) {
e.printStackTrace();
}
return failur;
}
protected void onPostExecute(boolean fail) {
pDialog.dismiss();
if (message == true){
finish();
Toast.makeText(Login_new.this, message, Toast.LENGTH_LONG).show();
}
} }}
答案 2 :(得分:0)
原因是json.toString()有时根据您的服务器代码为空,因此您将获得NullPointerException。
删除该行
Log.d("Login attempt", json.toString());
Log.d("Successfully Login!", json.toString());
答案 3 :(得分:0)
将以下代码放在onPostExecute()
而不是doInBackground()
Intent ii = new Intent(Login_new.this,MainActivity.class);
ii.putExtra(KEY_USERNAME, username);
finish();
startActivity(ii);
原因是您正在尝试完成当前的activity
并尝试启动新的activity
,而progressdialog
仍然显示这就是显示泄露的窗口错误的原因。并且doInBackground()
方法也期待String
作为回报。