在一个Android应用程序远程MySQL数据库交互 [英] Interacting with a Remote MySQL Database in an Android Application

查看:564
本文介绍了在一个Android应用程序远程MySQL数据库交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是当前工作在Android的客户端服务器通信。 我的工作在本教程上可以找到:<一href="http://www.mybringback.com/tutorial-series/12924/android-tutorial-using-remote-databases-php-and-mysql-part-1/" rel="nofollow">http://www.mybringback.com/tutorial-series/12924/android-tutorial-using-remote-databases-php-and-mysql-part-1/

为方便起见,我将只发布主要的活动页面(Java和XML)注册页面(Java和XML),因为这个问题是相同的其他类。

当我建立和月食,pressing登录时运行的项目或注册于registerlayout.xml按钮,整个应用程序会崩溃。是什么原因造成这个错误?请帮助!

错误code可以在下面找到

MainActivity.java

 包com.example.mysqltest;

进口的java.util.ArrayList;
进口的java.util.List;

进口org.apache.http.NameValuePair;
进口org.apache.http.message.BasicNameValuePair;
进口org.json.JSONException;
进口org.json.JSONObject;

进口android.app.Activity;
进口android.app.ProgressDialog;
进口android.content.Intent;
进口android.content.Shared preferences;
进口android.content.Shared preferences.Editor;
进口android.os.AsyncTask;
进口android.os.Bundle;
。进口的Andr​​oid preference preferenceManager。
进口android.util.Log;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.widget.Button;
进口android.widget.EditText;
进口android.widget.Toast;
公共类MainActivity扩展活动
实现OnClickListener {

私人的EditText用户,通过;
私人按钮mSubmit,mRegister;

//进度对话框
私人ProgressDialog pDialog;

// JSON解析器类
JSONParser jsonParser =新JSONParser();

// PHP登录脚本的位置:

//本地主机:
//您的设备上测试
//把你的本地IP,而不是在Windows中运行CMD&GT; IPCONFIG
//或在Mac终端输入ifconfig,并寻找下EN0或EN1的IP
//私有静态最后弦乐LOGIN_URL =HTTP://xxx.xxx.xx:1234 / web服务/login.php;

//在模拟器中进行测试:
私有静态最后弦乐LOGIN_URL =htt​​p://172.18.205.34/webservice/login.php;

//从真实服务器测试:
//私有静态最后弦乐LOGIN_URL =htt​​p://www.yourdomain.com/webservice/login.php;

// JSON元素的PHP脚本的repsonse IDS:
私有静态最后弦乐TAG_SUCCESS =成功;
私有静态最后弦乐TAG_MESSAGE =消息;

@覆盖
保护无效的onCreate(包savedInstanceState){
    // TODO自动生成方法存根
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);

    //设置输入字段
    用户=(EditText上)findViewById(R.id.getUsername);
    通过=(EditText上)findViewById(R.id.getPassword);

    //设置按钮
    mSubmit =(按钮)findViewById(R.id.btnLogin);
    mRegister =(按钮)findViewById(R.id.btnRegister);

    //注册监听器
    mSubmit.setOnClickListener(本);
    mRegister.setOnClickListener(本);

}

@覆盖
公共无效的onClick(视图v){
    // TODO自动生成方法存根
    开关(v.getId()){
    案例R.id.btnLogin:
            新AttemptLogin()执行()。
        打破;
    案例R.id.btnRegister:
            意图I =新的意图(这一点,Register.class);
            startActivity(ⅰ);
        打破;

    默认:
        打破;
    }
}

类AttemptLogin扩展的AsyncTask&LT;字符串,字符串,字符串&GT; {

     / **
     *在启动后台线程显示进度对话框
     * * /
    布尔故障= FALSE;

    @覆盖
    在preExecute保护无效(){
        super.on preExecute();
        pDialog =新ProgressDialog(MainActivity.this);
        pDialog.setMessage(试图登录......);
        pDialog.setIndeterminate(假);
        pDialog.setCancelable(真正的);
        pDialog.show();
    }

    @覆盖
    保护字符串doInBackground(字符串参数... args){
        // TODO自动生成方法存根
         //检查成功标签
        诠释成功;
        字符串username = user.getText()的toString()。
        字符串password = pass.getText()的toString()。
        尝试 {
            //大厦参数
            名单&LT;的NameValuePair&GT; PARAMS =新的ArrayList&LT;的NameValuePair&GT;();
            params.add(新BasicNameValuePair(用户名,用户名));
            params.add(新BasicNameValuePair(密码,密码));

            Log.d(!要求,出发);
            //获取产品的详细信息通过HTTP请求
            JSONObject的JSON = jsonParser.makeHtt prequest(
                   LOGIN_URL,POST,则params);

            //检查你的日志,JSON响应
            Log.d(登录尝试,json.toString());

            // json的成功标签
            成功= json.getInt(TAG_SUCCESS);
            如果(成功== 1){
                Log.d(登录成功!,json.toString());
                //保存用户数据
                共享preferences SP = preferenceManager
                        .getDefaultShared preferences(MainActivity.this);
                编辑器编辑= sp.edit();
                edit.putString(用户名,用户名);
                edit.commit();

                意图I =新的意图(MainActivity.this,ReadComments.class);
                完();
                startActivity(ⅰ);
                返回json.getString(TAG_MESSAGE);
            } 其他 {
                Log.d(登录失败!,json.getString(TAG_MESSAGE));
                返回json.getString(TAG_MESSAGE);
            }
        }赶上(JSONException E){
            e.printStackTrace();
        }

        返回null;

    }
    / **
     *在完成后台任务之后关闭该进度对话框
     * ** /
    保护无效onPostExecute(字符串file_url){
        //关闭该对话框,一旦产品中删除
        pDialog.dismiss();
        如果(file_url!= NULL){
            Toast.makeText(MainActivity.this,file_url,Toast.LENGTH_LONG).show();
        }

    }

}

}
 

activity_main.xml

 &LT; RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:工具=htt​​p://schemas.android.com/tool​​s
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:paddingBottom会=@扪/ activity_vertical_margin
机器人:以下属性来=@扪/ activity_horizo​​ntal_margin
机器人:paddingRight =@扪/ activity_horizo​​ntal_margin
机器人:paddingTop =@扪/ activity_vertical_margin
工具:上下文=MainActivity。&GT;

&LT;的EditText
    机器人:ID =@ + ID / getPassword来
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_alignLeft =@ + ID / getUsername
    机器人:layout_below =@ + ID / getUsername
    机器人:layout_marginTop =35dp
    机器人:EMS =10
    机器人:inputType =textMultiLine/&GT;

&LT;按钮
    机器人:ID =@ + ID / btnLogin
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_alignRight =@ + ID / textView1
    机器人:layout_centerVertical =真
    机器人:文本=登陆/&GT;

&LT;按钮
    机器人:ID =@ + ID / btnRegister
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_alignBaseline =@ + ID / btnLogin
    机器人:layout_alignBottom =@ + ID / btnLogin
    机器人:layout_centerHorizo​​ntal =真
    机器人:文本=注册/&GT;

&LT;的TextView
    机器人:ID =@ + ID / textView1
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_alignParentTop =真
    机器人:layout_marginTop =17dp
    机器人:layout_toLeftOf =@ + ID / btnRegister
    机器人:文本=用户名:/&GT;

&LT;的EditText
    机器人:ID =@ + ID / getUsername
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_alignLeft =@ + ID / textView1
    机器人:layout_below =@ + ID / textView1
    机器人:EMS =10
    机器人:inputType =textMultiLine&GT;

    &LT;不是requestFocus /&GT;
&LT; /的EditText&GT;

&LT;的TextView
    机器人:ID =@ + ID / textView2
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_alignLeft =@ + ID / getPassword来
    机器人:layout_below =@ + ID / getUsername
    机器人:layout_marginTop =17dp
    机器人:文本=密码:/&GT;

&LT; / RelativeLayout的&GT;
 

registerlayout.xml

 &LT; XML版本=1.0编码=UTF-8&GT?;
&LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:方向=垂直&GT;

&LT;的TextView
    机器人:ID =@ + ID / textView1
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=用户名/&GT;

&LT;的EditText
    机器人:ID =@ + ID / getUsername1
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:EMS =10
    机器人:inputType =textMultiLine&GT;

    &LT;不是requestFocus /&GT;
&LT; /的EditText&GT;

&LT;的TextView
    机器人:ID =@ + ID / textView2
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=密码/&GT;

&LT;的EditText
    机器人:ID =@ + ID / getPassword1
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:EMS =10
    机器人:inputType =textMultiLine/&GT;

&LT;按钮
    机器人:ID =@ + ID / btnRegister1
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=注册/&GT;

&LT; / LinearLayout中&GT;
 

Register.java

 包com.example.mysqltest;

进口的java.util.ArrayList;
进口的java.util.List;
进口org.apache.http.NameValuePair;
进口org.apache.http.message.BasicNameValuePair;
进口org.json.JSONException;
进口org.json.JSONObject;
进口android.app.Activity;
进口android.app.ProgressDialog;
进口android.os.AsyncTask;
进口android.os.Bundle;
进口android.util.Log;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.widget.Button;
进口android.widget.EditText;
进口android.widget.Toast;

公共类注册扩展活动实现OnClickListener {

私人的EditText用户,通过;
私人按钮mRegister;

 //进度对话框
私人ProgressDialog pDialog;

// JSON解析器类
JSONParser jsonParser =新JSONParser();

// PHP登录脚本

//本地主机:
//您的设备上测试
//把你的本地IP,而不是在Windows中运行CMD&GT; IPCONFIG
//或在Mac终端输入ifconfig,并寻找下EN0或EN1的IP
//私有静态最后弦乐LOGIN_URL =HTTP://xxx.xxx.xx:1234 / web服务/register.php;

//在模拟器中进行测试:
私有静态最后弦乐LOGIN_URL =htt​​p://192.168.1.38/webservice/register.php;

//从真实服务器测试:
//私有静态最后弦乐LOGIN_URL =htt​​p://www.yourdomain.com/webservice/register.php;

// IDS
私有静态最后弦乐TAG_SUCCESS =成功;
私有静态最后弦乐TAG_MESSAGE =消息;

@覆盖
保护无效的onCreate(包savedInstanceState){
    // TODO自动生成方法存根
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.registerlayout);

    用户=(EditText上)findViewById(R.id.getUsername1);
    通过=(EditText上)findViewById(R.id.getPassword1);

    mRegister =(按钮)findViewById(R.id.btnRegister1);
    mRegister.setOnClickListener(本);

}

@覆盖
公共无效的onClick(视图v){
    // TODO自动生成方法存根

            新CREATEUSER()执行()。

}

类CREATEUSER扩展的AsyncTask&LT;字符串,字符串,字符串&GT; {

     / **
     *在启动后台线程显示进度对话框
     * * /
    布尔故障= FALSE;

    @覆盖
    在preExecute保护无效(){
        super.on preExecute();
        pDialog =新ProgressDialog(Register.this);
        pDialog.setMessage(创建用户......);
        pDialog.setIndeterminate(假);
        pDialog.setCancelable(真正的);
        pDialog.show();
    }

    @覆盖
    保护字符串doInBackground(字符串参数... args){
        // TODO自动生成方法存根
         //检查成功标签
        诠释成功;
        字符串username = user.getText()的toString()。
        字符串password = pass.getText()的toString()。
        尝试 {
            //大厦参数
            名单&LT;的NameValuePair&GT; PARAMS =新的ArrayList&LT;的NameValuePair&GT;();
            params.add(新BasicNameValuePair(用户名,用户名));
            params.add(新BasicNameValuePair(密码,密码));

            Log.d(!要求,出发);

            //发布的用户数据脚本
            JSONObject的JSON = jsonParser.makeHtt prequest(
                   LOGIN_URL,POST,则params);

            //全JSON响应
            Log.d(登录尝试,json.toString());

            // json的成功要素
            成功= json.getInt(TAG_SUCCESS);
            如果(成功== 1){
                Log.d(用户创造的!,json.toString());
                完();
                返回json.getString(TAG_MESSAGE);
            }其他{
                Log.d(登录失败!,json.getString(TAG_MESSAGE));
                返回json.getString(TAG_MESSAGE);

            }
        }赶上(JSONException E){
            e.printStackTrace();
        }

        返回null;

    }
    / **
     *在完成后台任务之后关闭该进度对话框
     * ** /
    保护无效onPostExecute(字符串file_url){
        //关闭该对话框,一旦产品中删除
        pDialog.dismiss();
        如果(file_url!= NULL){
            Toast.makeText(Register.this,file_url,Toast.LENGTH_LONG).show();
        }

    }

}

}
 

的config.inc.php

 &LT; PHP

//这些变量定义了连接信息的MySQL数据库
$用户名=艾米丽;
$密码=测试;
$主机=localhost的;
$ DBNAME =web服务;


$选项=阵列(PDO :: MYSQL_ATTR_INIT_COMMAND =&GT;'SET NAMES UTF8);


尝试
{

    $ DB =新PDO(mysql的:主机= {$主机}; DBNAME = {$ DBNAME};字符集= UTF8,$用户名,密码$,$选择);
}
赶上(PDOException $前)
{

    模具(无法连接到数据库:$ EX-&GT;的getMessage());
}


$ DB-&GT;的setAttribute(PDO :: ATTR_ERRMODE,PDO :: ERRMODE_EXCEPTION);



$ DB-&GT;的setAttribute(PDO :: ATTR_DEFAULT_FETCH_MODE,PDO :: FETCH_ASSOC);



如果(function_exists('get_magic_quotes_gpc')及&安培; get_magic_quotes_gpc())
{
    功能undo_magic_quotes_gpc(安培; $阵列)
    {
        的foreach($阵列和放大器; $值)
        {
            如果(is_array($值))
            {
                undo_magic_quotes_gpc($值);
            }
            其他
            {
                $值=函数stripslashes($值);
            }
        }
    }

    undo_magic_quotes_gpc($ _ POST);
    undo_magic_quotes_gpc($ _ GET);
    undo_magic_quotes_gpc($ _ COOKIE);
}


标题(内容类型:text / html的;字符集= UTF-8);


在session_start();



?&GT;
 

的login.php

 &LT; PHP

//装载并连接到MySQL数据库的东西
要求(config.inc.php文件);

如果(!空($ _ POST)){
//获取基于掀起了用户名的用户信息。
$查询=
        选择
            ID,
            用户名,
            密码
        从用户
        哪里
            用户名=:用户名
    ;

$ query_params =阵列(
    :用户名=&GT; $ _ POST [用户名]
);

尝试 {
    $语句= $ DB-&GT; prepare($查询);
    $结果= $ stmt-&GT;执行($ query_params);
}
赶上(PDOException $前){
    //为了测试,你可以使用一个模具和消息。
    //模具(无法运行的问题:$ EX-&GT;的getMessage());

    //或者只是用这个使用这个产品JSON数据:
    $响应[成功] = 0;
    $响应[信息] =数据库ERROR1请重试!;
    死亡(json_en code($响应));

}

//这将是变量,以确定该用户的信息是否是正确的。
//我们初始化它为假。
$ validated_info = FALSE;

//获取所有行从查询
$行= $ stmt-&GT;取();
如果($行){
    //如果我们加密的密码,我们会解密在这里,但在我们的例子中,我们只
    //比较两个密码
    如果($ _ POST ['密码'] === $行['密码']){
        $ login_ok = TRUE;
    }
}

//如果用户登录成功,那么我们将它们发送到私有成员,只有页面
//否则,我们会显示登录失败的消息,并再次显示登录表单
如果($ login_ok){
    $响应[成功] = 1;
    $响应[信息] =登录成功!;
    死亡(json_en code($响应));
} 其他 {
    $响应[成功] = 0;
    $响应[信息] =!凭据无效;
    死亡(json_en code($响应));
}
} 其他 {
?&GT;
    &LT; H1&GT;登录&LT; / H1&GT;
      &LT;形式的行动=login.php中方法=邮报&GT;
        用户名:LT; BR /&GT;
        &LT;输入类型=文本名称=用户名占位符=用户名/&GT;
        &LT; BR /&GT;&LT; BR /&GT;
        密码:&LT; BR /&GT;
        &LT;输入类型=密码NAME =密码占位符=密码值=/&GT;
        &LT; BR /&GT;&LT; BR /&GT;
        &LT;输入类型=提交值=登陆/&GT;
    &LT; /形式GT;
    &所述; A HREF =register.php&GT;寄存器&所述; / a取代;
&LT; PHP
}

?&GT;
 

register.php

 &LT; PHP


要求(config.inc.php文件);

//如果贴的数据不为空
如果(!空($ _ POST)){
//如果用户名或密码为空,当用户提交
//形式,页面就会死亡。
//使用模具是不是一个很好的做法,你可能想看看
//显示错误消息在表单中代替。
//我们也可以做前端的表单验证从内部我们Android应用程序,
//但是这是好事,有一个具有后端code做了仔细检查。
如果(空($ _ POST ['用户名'])||空($ _ POST ['密码'])){


    //创建一些数据,这将是JSON响应
    $响应[成功] = 0;
    $响应[信息] =请输入了用户名和密码;

    //模具将杀死网页,不执行任何code以下,这也将
    //显示参数......在这种情况下,JSON数据我们的Andr​​oid
    //应用程序将解析
    死亡(json_en code($响应));
}

//如果页面还没有死,我们将与我们的数据库检查,看看是否有
//已经与specificed形式的用户名的用户。 :用户只是
//之前我们执行的查询,我们将改变一个空白的变量。我们
//做这种方式来提高安全性,以及对SQL注入防御
$查询=选择1从用户其中username =:用户;
//现在让我们更新的内容:用户应
$ query_params =阵列(
    :用户'=&GT; $ _ POST [用户名]
);

//现在让我们运行查询:
尝试 {
    //这两句话请对你的数据库表的查询。
    $语句= $ DB-&GT; prepare($查询);
    $结果= $ stmt-&GT;执行($ query_params);
}
赶上(PDOException $前){
    //为了测试,你可以使用一个模具和消息。
    //模具(无法运行的问题:$ EX-&GT;的getMessage());

    //或者只是用这个使用这个产品JSON数据:
    $响应[成功] = 0;
    $响应[信息] =数据库ERROR1请重试!;
    死亡(json_en code($响应));
}

//获取返回数据的数组。如果有任何数据返回,
//我们知道用​​户名已被使用,所以我们杀死我们
//页
$行= $ stmt-&GT;取();
如果($行){
    //为了测试,你可以使用一个模具和消息。
    //模具(该用户名已在使用);

    //你可以注释掉上面的芯片,并使用这一个:
    $响应[成功] = 0;
    $响应[信息] =对不起,该用户名已经被使用;
    死亡(json_en code($响应));
}

//如果我们取得了在这里没有死,那么我们都在昭示
//创建一个新用户。让我们建立我们新的查询来创建一个用户。
//再一次,以防止SQL其注入,用户令牌例如:用户:通
$查询=插入用户(用户名,密码)VALUES(:用户:通过);

//再一次,我们需要用实际数据来更新我们的标记:
$ query_params =阵列(
    :用户'=&GT; $ _ POST ['用户名'],
    :通过'=&GT; $ _ POST ['密码']
);

//时间来运行我们的查询,并创建用户
尝试 {
    $语句= $ DB-&GT; prepare($查询);
    $结果= $ stmt-&GT;执行($ query_params);
}
赶上(PDOException $前){
    //为了测试,你可以使用一个模具和消息。
    //模具(无法运行的问题:$ EX-&GT;的getMessage());

    //或者只是使用这种使用这一个:
    $响应[成功] = 0;
    $响应[信息] =数据库误差2,请重试!;
    死亡(json_en code($响应));
}

//如果我们没有死了这么远,我们已经成功添加
//一个新的用户来我们的数据库。我们可以做一些事情在这里,如
//重定向到登录页面。相反,我们要呼应了一些
将由Android的应用程序可以读取// JSON数据,这将登陆
//用户(或重定向到一个不同的活动,我现在还无法确定。)
$响应[成功] = 1;
$响应[信息] =用户名添加成功!;
回声json_en code($响应);

//一个PHP Web服务,你可以做一个简单的重定向和死亡。
//标题(位置:login.php中);
//模具(重定向到的login.php);


} 其他 {
?&GT;
&LT; H1&GT;注册&LT; / H1&GT;
&LT;形式的行动=register.php方法=邮报&GT;
    用户名:LT; BR /&GT;
    &LT;输入类型=文本名称=用户名值=/&GT;
    &LT; BR /&GT;&LT; BR /&GT;
    密码:&LT; BR /&GT;
    &LT;输入类型=密码NAME =密码值=/&GT;
    &LT; BR /&GT;&LT; BR /&GT;
    &LT;输入类型=提交值=注册新用户/&GT;
&LT; /形式GT;
&LT; PHP
}

?&GT;
 

错误的logcat

  8月10号至28号:52:43.894:D / dalvikvm(833):GC_FOR_ALLOC释放71K,8%免费2660K / 2880K,暂停41ms,共53ms
八月10日至28日:52:44.004!:D /请求(833):首发
八月10日至28日:52:46.224:I /编舞(833):跳过30帧!该应用程序可能会做它的主线程的工作太多了。
八月10日至28日:52:46.524:D / dalvikvm(833):GC_CONCURRENT释放57K,7%免费3009K / 3212K,暂停84ms + 37ms,总297ms
八月10日至28日:52:47.064:E / JSON解析器(833):错误分析数据org.json.JSONException:值小于,java.lang.String类型的DOCTYPE不能转换到的JSONObject
八月10日至28日:52:47.064:W / dalvikvm(833):主题ID = 15:线程退出与未捕获的异常(组= 0x40a71930)
八月10日至28日:52:47.144:E / AndroidRuntime(833):致命异常:AsyncTask的#5
八月10日至28日:52:47.144:E / AndroidRuntime(833):java.lang.RuntimeException的:一个错误而执行doInBackground发生()
八月10日至28日:52:47.144:E / AndroidRuntime(833):在android.os.AsyncTask $ 3.done(AsyncTask.java:299)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在java.util.concurrent.FutureTask.setException(FutureTask.java:219)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在java.util.concurrent.FutureTask.run(FutureTask.java:239)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在android.os.AsyncTask $ SerialExecutor $ 1.运行(AsyncTask.java:230)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:573)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在java.lang.Thread.run(Thread.java:856)
八月10日至28日:52:47.144:E / AndroidRuntime(833):由:显示java.lang.NullPointerException
八月10日至28日:52:47.144:E / AndroidRuntime(833):在com.example.mysqltest.MainActivity $ AttemptLogin.doInBackground(MainActivity.java:128)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在com.example.mysqltest.MainActivity $ AttemptLogin.doInBackground(MainActivity.java:1)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在android.os.AsyncTask $ 2.call(AsyncTask.java:287)
八月10日至28日:52:47.144:E / AndroidRuntime(833):在java.util.concurrent.FutureTask.run(FutureTask.java:234)
八月10日至28日:52:47.144:E / AndroidRuntime(833):4 ...更多
八月10日至28日:52:47.864:I /编舞(833):跳过87帧!该应用程序可能会做它的主线程的工作太多了。
八月10日至28日:52:50.844:E /窗口管理器(833):活动com.example.mysqltest.MainActivity渗漏窗口com.android.internal.policy.impl.PhoneWindow $ DecorView {40d24b58 VE ....  -  [R .. ... ID 0,0-563,96}最初此处添加
八月10日至28日:52:50.844:E /窗口管理器(833):android.view.WindowLeaked:活动com.example.mysqltest.MainActivity渗漏窗口com.android.internal.policy.impl.PhoneWindow $ DecorView {40d24b58 VE。 ...  -  [R ..... ID 0,0-563,96}最初此处添加
八月10日至28日:52:50.844:E /窗口管理器(833):在android.view.ViewRootImpl&LT; INIT&GT;(ViewRootImpl.java:354)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.app.Dialog.show(Dialog.java:281)
八月10日至28日:52:50.844:E /窗口管理器(833):在com.example.mysqltest.MainActivity $ AttemptLogin.on preExecute(MainActivity.java:106)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.os.AsyncTask.execute(AsyncTask.java:534)
八月10日至28日:52:50.844:E /窗口管理器(833):在com.example.mysqltest.MainActivity.onClick(MainActivity.java:80)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.view.View.performClick(View.java:4204)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.view.View $ PerformClick.run(View.java:17355)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.os.Handler.handleCallback(Handler.java:725)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.os.Handler.dispatchMessage(Handler.java:92)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.os.Looper.loop(Looper.java:137)
八月10日至28日:52:50.844:E /窗口管理器(833):在android.app.ActivityThread.main(ActivityThread.java:5041)
八月10日至28日:52:50.844:E /窗口管理器(833):在java.lang.reflect.Method.invokeNative(本机方法)
八月10日至28日:52:50.844:E /窗口管理器(833):在java.lang.reflect.Method.invoke(Method.java:511)
八月10日至28日:52:50.844:E /窗口管理器(833):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:793)
八月10日至28日:52:50.844:E /窗口管理器(833):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
八月10日至28日:52:50.844:E /窗口管理器(833):在dalvik.system.NativeStart.main(本机方法)
八月10日至28日:52:50.844:I /编舞(833):跳过73帧!该应用程序可能会做它的主线程的工作太多了。
 

解决方案

我有一个不同的错误,当我有这个问题,它说,的值小于; BR ... 不记得休息,但是,我发现是PHP中的问题。在您的login.php文件中,可以看到 $ validated_info = FALSE; ,但是,你实际使用的' $ login_ok 作为您的布尔变量。无论您在哪里看到 $ login_ok ,更改为 $ validated_info 。或更改 $ validated_info '到' $ login_ok 。这个固定矿的那一刻,但是我知道你的错误,当输入的详细信息不在数据库中。

i am current working on a client server communication in android. The tutorial that i am working on can be found on : http://www.mybringback.com/tutorial-series/12924/android-tutorial-using-remote-databases-php-and-mysql-part-1/

For convenience sake, i will only be posting main activity page (java and xml) and register page(java and xml) because the problem is the same for other class.

When i build and run the project on eclipse, pressing login OR register button in registerlayout.xml, the whole application will crash. What is causing this error? Please help!!!

Error code can be found below

MainActivity.java

package com.example.mysqltest;

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.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity 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:

//localhost :
//testing on your device
//put your local ip instead,  on windows, run CMD > ipconfig
//or in mac's terminal type ifconfig and look for the ip under en0 or en1
// private static final String LOGIN_URL = "http://xxx.xxx.x.x:1234/webservice  /login.php";

//testing on Emulator:
private static final String LOGIN_URL = "http://172.18.205.34/webservice/login.php";

//testing from a real server:
//private static final String LOGIN_URL = "http://www.yourdomain.com/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_main);

    //setup input fields
    user = (EditText)findViewById(R.id.getUsername);
    pass = (EditText)findViewById(R.id.getPassword);

    //setup buttons
    mSubmit = (Button)findViewById(R.id.btnLogin);
    mRegister = (Button)findViewById(R.id.btnRegister);

    //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.btnLogin:
            new AttemptLogin().execute();
        break;
    case R.id.btnRegister:
            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(MainActivity.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());
                // save user data
                SharedPreferences sp = PreferenceManager
                        .getDefaultSharedPreferences(MainActivity.this);
                Editor edit = sp.edit();
                edit.putString("username", username);
                edit.commit();

                Intent i = new Intent(MainActivity.this, ReadComments.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(MainActivity.this, file_url, Toast.LENGTH_LONG).show();
        }

    }

}

}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<EditText
    android:id="@+id/getPassword"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/getUsername"
    android:layout_below="@+id/getUsername"
    android:layout_marginTop="35dp"
    android:ems="10"
    android:inputType="textMultiLine" />

<Button
    android:id="@+id/btnLogin"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@+id/textView1"
    android:layout_centerVertical="true"
    android:text="Login" />

<Button
    android:id="@+id/btnRegister"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/btnLogin"
    android:layout_alignBottom="@+id/btnLogin"
    android:layout_centerHorizontal="true"
    android:text="Register" />

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_marginTop="17dp"
    android:layout_toLeftOf="@+id/btnRegister"
    android:text="Username:" />

<EditText
    android:id="@+id/getUsername"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/textView1"
    android:layout_below="@+id/textView1"
    android:ems="10"
    android:inputType="textMultiLine" >

    <requestFocus />
</EditText>

<TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/getPassword"
    android:layout_below="@+id/getUsername"
    android:layout_marginTop="17dp"
    android:text="Password:" />

</RelativeLayout>

registerlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Username" />

<EditText
    android:id="@+id/getUsername1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textMultiLine" >

    <requestFocus />
</EditText>

<TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Password" />

<EditText
    android:id="@+id/getPassword1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textMultiLine" />

<Button
    android:id="@+id/btnRegister1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Register" />

</LinearLayout>

Register.java

package com.example.mysqltest;

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.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Register extends Activity implements OnClickListener{

private EditText user, pass;
private Button  mRegister;

 // Progress Dialog
private ProgressDialog pDialog;

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

//php login script

//localhost :
//testing on your device
//put your local ip instead,  on windows, run CMD > ipconfig
//or in mac's terminal type ifconfig and look for the ip under en0 or en1
// private static final String LOGIN_URL = "http://xxx.xxx.x.x:1234/webservice   /register.php";

//testing on Emulator:
private static final String LOGIN_URL = "http://192.168.1.38/webservice/register.php";

//testing from a real server:
//private static final String LOGIN_URL = "http://www.yourdomain.com/webservice/register.php";

//ids
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.registerlayout);

    user = (EditText)findViewById(R.id.getUsername1);
    pass = (EditText)findViewById(R.id.getPassword1);

    mRegister = (Button)findViewById(R.id.btnRegister1);
    mRegister.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub

            new CreateUser().execute();

}

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

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

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(Register.this);
        pDialog.setMessage("Creating User...");
        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");

            //Posting user data to script
            JSONObject json = jsonParser.makeHttpRequest(
                   LOGIN_URL, "POST", params);

            // full json response
            Log.d("Login attempt", json.toString());

            // json success element
            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                Log.d("User Created!", json.toString());
                finish();
                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(Register.this, file_url, Toast.LENGTH_LONG).show();
        }

    }

}

}

config.inc.php

<?php 

// These variables define the connection information for your MySQL database 
$username = "emily"; 
$password = "testing"; 
$host = "localhost"; 
$dbname = "webservice"; 


$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); 


try 
{ 

    $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options); 
} 
catch(PDOException $ex) 
{ 

    die("Failed to connect to the database: " . $ex->getMessage()); 
} 


$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 



$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 



if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) 
{ 
    function undo_magic_quotes_gpc(&$array) 
    { 
        foreach($array as &$value) 
        { 
            if(is_array($value)) 
            { 
                undo_magic_quotes_gpc($value); 
            } 
            else 
            { 
                $value = stripslashes($value); 
            } 
        } 
    } 

    undo_magic_quotes_gpc($_POST); 
    undo_magic_quotes_gpc($_GET); 
    undo_magic_quotes_gpc($_COOKIE); 
} 


header('Content-Type: text/html; charset=utf-8'); 


session_start(); 



?>

login.php

<?php

//load and connect to MySQL database stuff
require("config.inc.php");

if (!empty($_POST)) {
//gets user's info based off of a username.
$query = " 
        SELECT 
            id, 
            username, 
            password
        FROM users 
        WHERE 
            username = :username 
    ";

$query_params = array(
    ':username' => $_POST['username']
);

try {
    $stmt   = $db->prepare($query);
    $result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
    // For testing, you could use a die and message. 
    //die("Failed to run query: " . $ex->getMessage());

    //or just use this use this one to product JSON data:
    $response["success"] = 0;
    $response["message"] = "Database Error1. Please Try Again!";
    die(json_encode($response));

}

//This will be the variable to determine whether or not the user's information is correct.
//we initialize it as false.
$validated_info = false;

//fetching all the rows from the query
$row = $stmt->fetch();
if ($row) {
    //if we encrypted the password, we would unencrypt it here, but in our case we just
    //compare the two passwords
    if ($_POST['password'] === $row['password']) {
        $login_ok = true;
    }
}

// If the user logged in successfully, then we send them to the private members-only page 
// Otherwise, we display a login failed message and show the login form again 
if ($login_ok) {
    $response["success"] = 1;
    $response["message"] = "Login successful!";
    die(json_encode($response));
} else {
    $response["success"] = 0;
    $response["message"] = "Invalid Credentials!";
    die(json_encode($response));
}
} else {
?>
    <h1>Login</h1> 
      <form action="login.php" method="post"> 
        Username:<br /> 
        <input type="text" name="username" placeholder="username" /> 
        <br /><br /> 
        Password:<br /> 
        <input type="password" name="password" placeholder="password" value="" /> 
        <br /><br /> 
        <input type="submit" value="Login" /> 
    </form> 
    <a href="register.php">Register</a>
<?php
}

?> 

register.php

<?php


require("config.inc.php");

//if posted data is not empty
if (!empty($_POST)) {
//If the username or password is empty when the user submits
//the form, the page will die.
//Using die isn't a very good practice, you may want to look into
//displaying an error message within the form instead.  
//We could also do front-end form validation from within our Android App,
//but it is good to have a have the back-end code do a double check.
if (empty($_POST['username']) || empty($_POST['password'])) {


    // Create some data that will be the JSON response 
    $response["success"] = 0;
    $response["message"] = "Please Enter Both a Username and Password.";

    //die will kill the page and not execute any code below, it will also
    //display the parameter... in this case the JSON data our Android
    //app will parse
    die(json_encode($response));
}

//if the page hasn't died, we will check with our database to see if there is
//already a user with the username specificed in the form.  ":user" is just
//a blank variable that we will change before we execute the query.  We
//do it this way to increase security, and defend against sql injections
$query        = " SELECT 1 FROM users WHERE username = :user";
//now lets update what :user should be
$query_params = array(
    ':user' => $_POST['username']
);

//Now let's make run the query:
try {
    // These two statements run the query against your database table. 
    $stmt   = $db->prepare($query);
    $result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
    // For testing, you could use a die and message. 
    //die("Failed to run query: " . $ex->getMessage());

    //or just use this use this one to product JSON data:
    $response["success"] = 0;
    $response["message"] = "Database Error1. Please Try Again!";
    die(json_encode($response));
}

//fetch is an array of returned data.  If any data is returned,
//we know that the username is already in use, so we murder our
//page
$row = $stmt->fetch();
if ($row) {
    // For testing, you could use a die and message. 
    //die("This username is already in use");

    //You could comment out the above die and use this one:
    $response["success"] = 0;
    $response["message"] = "I'm sorry, this username is already in use";
    die(json_encode($response));
}

//If we have made it here without dying, then we are in the clear to 
//create a new user.  Let's setup our new query to create a user.  
//Again, to protect against sql injects, user tokens such as :user and :pass
$query = "INSERT INTO users ( username, password ) VALUES ( :user, :pass ) ";

//Again, we need to update our tokens with the actual data:
$query_params = array(
    ':user' => $_POST['username'],
    ':pass' => $_POST['password']
);

//time to run our query, and create the user
try {
    $stmt   = $db->prepare($query);
    $result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
    // For testing, you could use a die and message. 
    //die("Failed to run query: " . $ex->getMessage());

    //or just use this use this one:
    $response["success"] = 0;
    $response["message"] = "Database Error2. Please Try Again!";
    die(json_encode($response));
}

//If we have made it this far without dying, we have successfully added
//a new user to our database.  We could do a few things here, such as 
//redirect to the login page.  Instead we are going to echo out some
//json data that will be read by the Android application, which will login
//the user (or redirect to a different activity, I'm not sure yet..)
$response["success"] = 1;
$response["message"] = "Username Successfully Added!";
echo json_encode($response);

//for a php webservice you could do a simple redirect and die.
//header("Location: login.php"); 
//die("Redirecting to login.php");


} else {
?>
<h1>Register</h1> 
<form action="register.php" method="post"> 
    Username:<br /> 
    <input type="text" name="username" value="" /> 
    <br /><br /> 
    Password:<br /> 
    <input type="password" name="password" value="" /> 
    <br /><br /> 
    <input type="submit" value="Register New User" /> 
</form>
<?php
}

?>

error logcat

10-28 08:52:43.894: D/dalvikvm(833): GC_FOR_ALLOC freed 71K, 8% free 2660K/2880K,   paused 41ms, total 53ms
10-28 08:52:44.004: D/request!(833): starting
10-28 08:52:46.224: I/Choreographer(833): Skipped 30 frames!  The application may be doing too much work on its main thread.
10-28 08:52:46.524: D/dalvikvm(833): GC_CONCURRENT freed 57K, 7% free 3009K/3212K, paused 84ms+37ms, total 297ms
10-28 08:52:47.064: E/JSON Parser(833): Error parsing data org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
10-28 08:52:47.064: W/dalvikvm(833): threadid=15: thread exiting with uncaught exception (group=0x40a71930)
10-28 08:52:47.144: E/AndroidRuntime(833): FATAL EXCEPTION: AsyncTask #5
10-28 08:52:47.144: E/AndroidRuntime(833): java.lang.RuntimeException: An error occured while executing doInBackground()
10-28 08:52:47.144: E/AndroidRuntime(833):  at android.os.AsyncTask$3.done(AsyncTask.java:299)
10-28 08:52:47.144: E/AndroidRuntime(833):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
10-28 08:52:47.144: E/AndroidRuntime(833):  at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
10-28 08:52:47.144: E/AndroidRuntime(833):  at java.util.concurrent.FutureTask.run(FutureTask.java:239)
10-28 08:52:47.144: E/AndroidRuntime(833):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-28 08:52:47.144: E/AndroidRuntime(833):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-28 08:52:47.144: E/AndroidRuntime(833):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-28 08:52:47.144: E/AndroidRuntime(833):  at java.lang.Thread.run(Thread.java:856)
10-28 08:52:47.144: E/AndroidRuntime(833): Caused by: java.lang.NullPointerException
10-28 08:52:47.144: E/AndroidRuntime(833):  at com.example.mysqltest.MainActivity$AttemptLogin.doInBackground(MainActivity.java:128)
10-28 08:52:47.144: E/AndroidRuntime(833):  at com.example.mysqltest.MainActivity$AttemptLogin.doInBackground(MainActivity.java:1)
10-28 08:52:47.144: E/AndroidRuntime(833):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-28 08:52:47.144: E/AndroidRuntime(833):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
10-28 08:52:47.144: E/AndroidRuntime(833):  ... 4 more
10-28 08:52:47.864: I/Choreographer(833): Skipped 87 frames!  The application may be doing too much work on its main thread.
10-28 08:52:50.844: E/WindowManager(833): Activity com.example.mysqltest.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{40d24b58 V.E.....    R.....ID 0,0-563,96} that was originally added here
10-28 08:52:50.844: E/WindowManager(833): android.view.WindowLeaked: Activity com.example.mysqltest.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{40d24b58 V.E..... R.....ID 0,0-563,96} that was originally added here
10-28 08:52:50.844: E/WindowManager(833):   at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
10-28 08:52:50.844: E/WindowManager(833):   at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
10-28 08:52:50.844: E/WindowManager(833):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
10-28 08:52:50.844: E/WindowManager(833):   at android.app.Dialog.show(Dialog.java:281)
10-28 08:52:50.844: E/WindowManager(833):   at com.example.mysqltest.MainActivity$AttemptLogin.onPreExecute(MainActivity.java:106)
10-28 08:52:50.844: E/WindowManager(833):   at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
10-28 08:52:50.844: E/WindowManager(833):   at android.os.AsyncTask.execute(AsyncTask.java:534)
10-28 08:52:50.844: E/WindowManager(833):   at com.example.mysqltest.MainActivity.onClick(MainActivity.java:80)
10-28 08:52:50.844: E/WindowManager(833):   at android.view.View.performClick(View.java:4204)
10-28 08:52:50.844: E/WindowManager(833):   at android.view.View$PerformClick.run(View.java:17355)
10-28 08:52:50.844: E/WindowManager(833):   at android.os.Handler.handleCallback(Handler.java:725)
10-28 08:52:50.844: E/WindowManager(833):   at android.os.Handler.dispatchMessage(Handler.java:92)
10-28 08:52:50.844: E/WindowManager(833):   at android.os.Looper.loop(Looper.java:137)
10-28 08:52:50.844: E/WindowManager(833):   at android.app.ActivityThread.main(ActivityThread.java:5041)
10-28 08:52:50.844: E/WindowManager(833):   at java.lang.reflect.Method.invokeNative(Native Method)
10-28 08:52:50.844: E/WindowManager(833):   at java.lang.reflect.Method.invoke(Method.java:511)
10-28 08:52:50.844: E/WindowManager(833):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-28 08:52:50.844: E/WindowManager(833):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-28 08:52:50.844: E/WindowManager(833):   at dalvik.system.NativeStart.main(Native Method)
10-28 08:52:50.844: I/Choreographer(833): Skipped 73 frames!  The application may be doing too much work on its main thread.

解决方案

I had a different error when I had this problem which said 'The value <br...' Can't remember the rest, however the problem that I found was within the PHP. In your Login.PHP file, you can see '$validated_info = false;', however, you are actually using '$login_ok' as your boolean variable. Wherever you see '$login_ok', change that to '$validated_info'. Or change '$validated_info' to '$login_ok'. This fixed mine for the moment, however I get your error when the details entered aren't in the database.

这篇关于在一个Android应用程序远程MySQL数据库交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆