嗨,我只是想让Android的用户登录和注册表单,我遇到了一个小问题,我无法理解它。我对编程很新,所以请耐心等待。
我有一个主活动类和一个Register活动类,它扩展了AsyncTask并连接到PHP文件。 当我将详细信息发送到PHP文件时,我得到一个或零的响应,指示用户是否存在。 在我的main方法中,我通过创建它的实例来执行Register类,如果电子邮件不存在则用户凭证将存储到数据库中,如果它确实存在则不存储。 我的问题是我得到的回应似乎没有通过使用getter和setter转回我的主类。 我已经在Register类中测试了响应并返回了“1”或“0”,但是通过从主类调用getter来访问响应,返回null。 在Register类打印值之前,还会从主类打印到logcat的输出。 如果有人能提供帮助我会非常感激。
package com.eanna.UserLogin;
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;
public class Main extends Activity {
private EditText username;
private EditText firstname;
private EditText surname;
private EditText password;
private EditText email;
private Button register;
private ProgressDialog pDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
username=(EditText) findViewById(R.id.editText1);
firstname=(EditText) findViewById(R.id.editText2);
surname=(EditText) findViewById(R.id.editText3);
password=(EditText) findViewById(R.id.editText4);
email=(EditText) findViewById(R.id.editText5);
register=(Button) findViewById(R.id.button1);
}
public void register(View v) {
String usernameStr = username.getText().toString();
String firstnameStr = firstname.getText().toString();
String surnameStr = surname.getText().toString();
String passwordStr = password.getText().toString();
String emailStr = email.getText().toString();
register registerInst = new register();
registerInst.execute(usernameStr,firstnameStr,surnameStr,passwordStr,emailStr);
System.out.println("Response Value(main class) is: "+registerInst.getValue() );
}
}
我的注册类
package com.eanna.UserLogin;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import android.os.AsyncTask;
public class register extends AsyncTask<String, Void, String> {
String value;
@Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try{
String username = (String)arg0[0];
String firstname = (String)arg0[1];
String surname = (String)arg0[2];
String password = (String)arg0[3];
String email = (String)arg0[4];
String link = "http://randomsite.com/randomphpfile.php";
String data=URLEncoder.encode("username", "UTF-8")
+ "=" + URLEncoder.encode(username, "UTF-8");
data+="&"+URLEncoder.encode("firstname", "UTF-8")
+ "=" + URLEncoder.encode(firstname, "UTF-8");
data+="&"+URLEncoder.encode("surname", "UTF-8")
+ "=" + URLEncoder.encode(surname, "UTF-8");
data+="&"+URLEncoder.encode("password", "UTF-8")
+ "=" + URLEncoder.encode(password, "UTF-8");
data+="&"+URLEncoder.encode("email", "UTF-8")
+ "=" + URLEncoder.encode(email, "UTF-8");
URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter
(conn.getOutputStream());
wr.write( data );
wr.flush();
BufferedReader reader = new BufferedReader
(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
sb.append(line);
break;
}
return sb.toString();
}catch(Exception e){
return new String("Exception: " + e.getMessage());
}
}
@Override
protected void onPostExecute(String result){
setValue(result);
System.out.println("Response Value (Register class) is: "+result);
}
public void setValue(String value){
this.value=value;
}
public String getValue(){
return value;
}
}
这是我的输出
03-03 19:53:12.302: D/libEGL(1091): loaded /system/lib/egl/libEGL_emulation.so
03-03 19:53:12.312: D/(1091): HostConnection::get() New Host Connection established 0x2a1f1df8, tid 1091
03-03 19:53:12.392: D/libEGL(1091): loaded /system/lib/egl/libGLESv1_CM_emulation.so
03-03 19:53:12.405: D/libEGL(1091): loaded /system/lib/egl/libGLESv2_emulation.so
03-03 19:53:12.482: W/EGL_emulation(1091): eglSurfaceAttrib not implemented
03-03 19:53:12.492: D/OpenGLRenderer(1091): Enabling debug mode 0
03-03 19:53:12.562: D/dalvikvm(1091): GC_FOR_ALLOC freed 78K, 8% free 2942K/3176K, paused 47ms, total 51ms
03-03 19:53:17.623: I/System.out(1091): Response Value(main class) is: null
03-03 19:53:18.049: I/System.out(1091): Response Value (Register class) is: 1
它首先输出主类system.out,即使它应该在
之后执行“registerInst.execute(usernameStr,firstnameStr,surnameStr,passwordStr,emailStr);”
感谢您的帮助。
答案 0 :(得分:2)
首先要小心你的register
变量。您首先将其定义为
register=(Button) findViewById(R.id.button1);
然后作为
register registerInst = new register();
这不一定是错误,但绝对是不良做法。
你对的看法它首先输出主类system.out,即使它应该在...之后执行... 不是bug。 AsyncTask(例如您的register
变量)在后台运行在一个单独的线程上。当您调用execute
时,无法保证线程将如何同时执行。最终,这就是AsyncTask的设计目的,在不阻塞主线程的情况下进行一些繁重的处理(Web请求......)!
答案 1 :(得分:1)
您的第一个println语句(响应值(主类))将始终立即执行,这就是它打印null的原因。然后,您的寄存器类将在单独的线程上执行处理并打印获取的值。换句话说,在完成提取内容后,将永远不会调用您的第一个println语句。
您可能要考虑的是在寄存器类中添加一个回调接口。这样,您的Activity可以实现它,将其传递给您的AsyncTask实现,然后在完成后触发回调。例如:
界面:
public interface Callback {
void onComplete(String response);
}
在您的注册类中:
private Callback mCallback;
public void setCallback(Callback callback) {
mCallback = callback;
}
@Override
public void onExecute(String result) {
mCallback.execute(result);
}
答案 2 :(得分:1)
由于主class.out是主线程的一部分而reisterInst.execute启动一个线程,所以这种行为很好“System.out.println(”响应值(主类)):“+ registerInst.getValue( ));“ line在并行线程完成执行之前执行。 UI线程在启动AsyncTask后没有被阻塞,那就是它应该如何。启动AsyncTask的目的是我们不想阻止UI /主要Tread。
这就是你的getVialue()返回0的原因,因为它在asynctask完成之前执行了。您可以在MainClass中编写处理程序并将结果发布到处理程序。
答案 3 :(得分:0)
有two threads
:一个用于AsyncTask
,另一个用于main class
对于第一个(AsyncTask):可能需要几次才能完成其任务,并在第二个线程(Main)之后完成。
因此System.out.println("Response Value(main class) is: "+registerInst.getValue() );
可以在System.out.println("Response Value (Register class) is: "+result);