繁体   English   中英

使用HttpClient进行登录身份验证

[英]Use HttpClient for login authentication

我正在尝试向php文件发送POST请求,当要求用户提供登录信息时,如果输入错误,它将打印php文件中的json消息;如果正确,则允许用户登录。 但是,我的应用程序崩溃了,并给出了一个NetworkOnThreadMainException,将错误指向三行。

 HttpResponse response=httpClient.execute(httpPost);

public class LoginActivity extends ActionBarActivity  {

login();

那么我怎样才能做到这一点呢? 这是我编写的代码的一部分:

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 + "\n");
        }
    } 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个主线程在不暂停时一直运行,这称为UI Thread

从最新版本的Android开始,您不允许在UI Thread上进行任何与网络相关的操作,因为这很耗时,并且会阻塞负责绘制所有用户界面和注册点击等的主线程。有一种绕过此方法的方法,但HIGHLY NOT RECOMMENDED

执行network related actions例如登录)的一种简单方法是Android实现的AsyncTask类。

该类以非常简单的原理运行,它有2个在UI Thread上运行的方法: onPreExecute()onPostExecute()方法。

它有一个在Background Thread上运行的方法,该方法称为doInBackground() (在此处应执行所有与网络相关的操作

这是AsyncTask类的一个非常基本的示例:

 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)
     }
 }

要使用此任务,您可以像这样从UI Thread简单地调用它:

new DownloadFilesTask().execute();

这是developer.android.com上的AsyncTask文档页面: AsyncTask

您可以通过任务的构造函数传递对LoginActivity的引用,如果登录有效,则可以从任务内的onPostExecute()调用navigatetoMainActivity()方法。

Edit1:LoginActivity的外观:

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:这是您的任务应如下所示:

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();
}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM