duanmei1885 2015-11-09 18:12
浏览 374
已采纳

使用HttpClient进行登录验证

I am trying to send a POST request to a php file and when the user is asked for login information, if wrong, it prints the json message from the php file and if right, it allows user to login. However, my application crashes, giving a NetworkOnThreadMainException pointing errors to three lines.

 HttpResponse response=httpClient.execute(httpPost);

public class LoginActivity extends ActionBarActivity  {

login();

So how can i make this possible? This is some part of the code I have written:

public class LoginActivity extends ActionBarActivity  {
EditText et, et2;
ImageButton ib5;
String name,pwd;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    et = (EditText) findViewById(R.id.editText);
    et2 = (EditText) findViewById(R.id.editText2);
    ib5 = (ImageButton) findViewById(R.id.imageButton5);

    name=et.getText().toString();
    pwd=et2.getText().toString();
    final LoginActivity loginActivity=null;

    ib5.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //login();
            new DownloadFilesTask(loginActivity,name,pwd).doInBackground();
        }
    });

}

public void login() {
    new LoginTask(this, et.getText().toString(), et2.getText().toString());
}


private class LoginTask {
    public LoginTask(LoginActivity loginActivity, String name, String pwd) {
    }
}

void navigatetoMainActivity() {
    Intent homeIntent = new Intent(getApplicationContext(), MainActivity.class);
    homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(homeIntent);
}

void InvalidToast(){
    Toast.makeText(getApplicationContext(), "Please enter valid name and password", Toast.LENGTH_LONG).show();
}
void EmptyToast(){
    Toast.makeText(getApplicationContext(), "Please fill the form, don't leave any field blank", Toast.LENGTH_LONG).show();
}
}

DownloadFilesTask.java

public class DownloadFilesTask extends AsyncTask<String, String, String> {

private String name, pwd;
private LoginActivity loginActivity;

public DownloadFilesTask(LoginActivity loginActivity,String name, String pwd){
    this.loginActivity=loginActivity;
    this.name=name;
    this.pwd=pwd;
}

@Override
protected String doInBackground(String... strings) {
    HttpClient httpClient=new DefaultHttpClient();
    HttpPost httpPost=new HttpPost("login.php");
    List<NameValuePair> nameValuePairs=new ArrayList<NameValuePair>(2);
    String result=null;
    nameValuePairs.add(new BasicNameValuePair("name", name));
    nameValuePairs.add(new BasicNameValuePair("password", pwd));
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    HttpResponse response= null;
    try {
        response = httpClient.execute(httpPost);  //error is given here
    } catch (IOException e) {
        e.printStackTrace();
    }
    HttpEntity entity=response.getEntity();
    InputStream instream= null;
    try {
        instream = entity.getContent();
    } catch (IOException e) {
        e.printStackTrace();
    }
    result=convertStreamToString(instream);
    try {
        instream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }



    if (Utility.isNotNull(name) && Utility.isNotNull(pwd)) {
        RequestParams params = new RequestParams();
        if (Utility.validate(name, pwd)) {
            params.put("username", name);
            params.put("password", pwd);
            onPostExecute();
        } else {
            loginActivity.InvalidToast();
        }
    } else {
        loginActivity.EmptyToast();
    }
    return result;
}


private String convertStreamToString(InputStream instream) {
    BufferedReader reader=new BufferedReader(new InputStreamReader(instream));
    StringBuilder sb=new StringBuilder();
    String line=null;
    try {
        while ((line=reader.readLine())!=null){
            sb.append(line + "
");
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
        try {
            instream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();
}

protected void onPostExecute(){
    loginActivity.navigatetoMainActivity();
}



private static class Utility {
    static Pattern pattern;
    static Matcher matcher;
    static Pattern pattern1;
    static Matcher matcher1;
    static String NAME_PATTERN="SuperBoise";
    static String PWD_PATTERN="qwerty";

    public static boolean validate(String name,String pwd){
        pattern=Pattern.compile(NAME_PATTERN);
        pattern1=Pattern.compile(PWD_PATTERN);
        matcher=pattern.matcher(name);
        matcher1=pattern1.matcher(pwd);
        return matcher.matches()&& matcher1.matches();
    }

    public static boolean isNotNull(String name) {
        return name!=null && name.trim().length()>0 ? true: false;
    }
}
}
  • 写回答

1条回答 默认 最新

  • dongyao1915 2015-11-09 18:45
    关注

    Your application has 1 main thread running all the time when it is not paused which is called the UI Thread.

    As of the latest versions of Android, you are not permitted to make any network related actions on the UI Thread because it is time-consuming and it blocks the main thread which is responsible for drawing all the UI and registering the clicks, etc. (there is a way to bypass this but it is HIGHLY NOT RECOMMENDED)

    An easy way to perform network related actions such as logging in, is the AsyncTask class implemented by Android.

    The class runs on a very simple principle, it has 2 methods which run on the UI Thread: the onPreExecute() and the onPostExecute() methods.

    And it has a method that runs on a Background Thread which is called the doInBackground() (this is where you should do all your network related actions

    Here is a very basic example of an AsyncTask class:

     public class DownloadFilesTask extends AsyncTask<void, void, void> {
    
         public DownloadFilesTask(){
              // Here you can pass data to the task
              // if you want to pass more than 1 type of data
         }
    
         protected void onPreExecute(){
             // this is executed on the UI Thread 
             // so you can modify elements inside the UI Thread
             // this is called after execute() is called and 
             // before doInBackground() is called
         }
    
         protected void doInBackground(Void... params) {
             //here you do all your network related stuff
             return null;
         }
    
         protected void onPostExecute(Void result) {
             // here you can work on the UI Thread
             // this is executed after the AsyncTask's execute() is finished
             // (after doInBackground() is done)
         }
     }
    

    And to use this task you can just simply call it from the UI Thread like this:

    new DownloadFilesTask().execute();
    

    This is the AsyncTask documentation page on the developer.android.com: AsyncTask

    You could pass a reference to your LoginActivity through the constructor of the task and if the login is valid then you can call the navigatetoMainActivity() method from your onPostExecute() inside the task

    Edit1: How your LoginActivity should look:

    public class LoginActivity extends ActionBarActivity  {
    EditText et, et2;
    ImageButton ib5;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
    
        et = (EditText) findViewById(R.id.editText);
        et2 = (EditText) findViewById(R.id.editText2);
        ib5 = (ImageButton) findViewById(R.id.imageButton5);
    
        ib5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                login();
            }
        });
    }
    
    public void login(){
        new LoginTask(this, et.getText().toString(), et2.getText.toString()).execute();
    }
    }
    

    Edit2: This is how your task should look like:

    public class LoginTask extends AsyncTask<void , void, void> {
    
    private String user, password;
    private LoginActivity loginActivity;
    
    public LoginTask(LoginActivity loginActivity, String user, String password){
         this.loginActivity = loginActivity;
         this.user = user;
         this.password = password;
    }
    @Override
    protected String doInBackground(Void... params) {
         //do all the networking here
    }
    
    protected void onPostExecute(Void results){
         super.onPostExecute(results);
         loginActivity.navigatetoMainActivity();
    }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?