Использовать HttpClient для аутентификации входа

Я пытаюсь отправить POST-запрос в php-файл, и когда у пользователя запрашивается информация для входа в систему, в случае ошибки он печатает сообщение json из php-файла и, если это так, позволяет пользователю войти в систему. Однако мое приложение вылетает, вызывая исключение 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;
}
}
}

0

Решение

Ваше приложение имеет 1 основной поток, работающий все время, когда оно не приостановлено, которое называется UI Thread,

Начиная с последних версий Android, вы не можете выполнять какие-либо действия, связанные с сетью, на UI Thread потому что это отнимает много времени и блокирует основной поток, который отвечает за отрисовку всего пользовательского интерфейса, регистрацию кликов и т. д. (есть способ обойти это, но это HIGHLY NOT RECOMMENDED)

Простой способ выполнить network related actions такие как вход в систему, является AsyncTask Класс реализован на Android.

Класс работает по очень простому принципу, он имеет 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();

Это страница документации AsyncTask на developer.android.com: AsyncTask

Вы можете передать ссылку на свой LoginActivity через конструктор задачи, и если логин действителен, вы можете вызвать navigatetoMainActivity() метод из вашего onPostExecute() внутри задачи

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

Другие решения

Других решений пока нет …