扩展Asynctask的类的实例并不完全有效

时间:2014-03-04 01:03:32

标签: java android android-asynctask

嗨,我只是想让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);”​​

感谢您的帮助。

4 个答案:

答案 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);

之前显示结果