1

I was writing an Android Login Page and i used a Class that extended AsyncTask.

The problem is that it seems that i can't "control" the flow of the Async Task.

If i insert correct username and password, if i click one time when it connects to the database it says that they are incorrect but if i press a second time it works.

Luckily, it does not happen when i insert wrong user or password.

I used a boolean variable that shows me if password and username are correct.

 public class LoginPage extends Activity implements OnClickListener {
 public boolean loginCorrect=false;
 //other code
 }

then i implemented the OnClick(View v) function:

 public void onClick(View v)
 {//switch related code
    case(R.id.btn_submit):{
    connectToDB(v);
if(loginCorrect)
{loginCorrect=false // If i have to login another time, it will make all the needed checks 
Intent intent = new Intent(this, MainPage.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);  
finish();
startActivity(intent);   
}
    else
{Toast.makeText(getApplicationContext(),"Email or password is incorrect", 
        Toast.LENGTH_SHORT).show();


}
break;
//other code

In connectToDb(v):

   public void connectToDB(View view)
   {
  ConnectAsync task = new ConnectAsync();
   task.execute();

     }

And in doInBackground

        @Override
        protected String doInBackground(String... urls) {

            String url= //jdbc string
            String user=insUser.getText().toString();
            String password=insPw.getText().toString();
            Connection connessione=null;
            Statement statement=null;
            ResultSet resultSet=null;
            String sql=//sql query
            try{        Class.forName //driver loading
            connessione=DriverManager.getConnection(url,user,password);
                statement=connessione.createStatement();
                resultSet=statement.executeQuery(sql);
                if(resultSet.next())
                    if( //i found a tuple with that username and   that  password
                    {

                        loginCorrect=true;
                    }
                connessione.close();

            }
            catch (SQLException se){
                //exception related code
            }
            catch (ClassNotFoundException cnfe) {
                //exception related code
            }


       return null;
        }
EagleOne
  • 541
  • 1
  • 10
  • 28
  • [See here](http://stackoverflow.com/questions/18517400/inner-class-can-access-but-not-update-values-asynctask) you need to wait for the task to get done before checking the value – codeMagic May 13 '15 at 00:29

3 Answers3

2

The problem is that by definition an AsyncTask is not run on the UI thread. So by doing this :

connectToDB(v);
if(loginCorrect)

You will not wait for the end of the AsyncTask to check the value. I suggest you implement the onPostExecute method of the AsyncTask that will be called on the UI thread after the end of the AsyncTask. Something like this:

@Override
protected void onPostExecute(YOUR_TYPE result) {
if(loginCorrect)
{loginCorrect=false // If i have to login another time, it will make all the needed checks 
Intent intent = new Intent(this, MainPage.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);  
finish();
startActivity(intent);   
}
    else
{Toast.makeText(getApplicationContext(),"Email or password is incorrect", 
        Toast.LENGTH_SHORT).show();


}
}
Patrick
  • 268
  • 1
  • 5
1

First you need to override onPostExecute function of AsyncTask that will handle the result of your query. You can either call a function from your Activity or add the code in onPostExecute.

class ConnectToDBTask extends AsyncTask<Void,Void,Boolean>
  {
    @Override
    protected Boolean doInBackground(Void... params)
    {
      Boolean bResult = false;
      try
      {
        bResult = true;
      }
      catch (Exception se)
      {
      }


      return bResult;

    }

    @Override
    protected void onPostExecute(Boolean aBoolean)
    {
      if ( aBoolean == true)
      {
        Main.this.HandleLoginResult(aBoolean);
      }
      super.onPostExecute(aBoolean);
    }

  }

Then you can add a function in your activity that will call the intent if Login is successful.

public void HandleLoginResult(Boolean bResult)
  {
    if ( bResult == true)
    {
      Intent intent = new Intent(this, Main.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      intent.putExtra("EXIT", true);
      finish();
      startActivity(intent);
    }
  }
Christian Abella
  • 5,747
  • 2
  • 30
  • 42
0

You never check if the user presses the button again before your asynctask finishes. You can set btn_submit.setClickable(false) , and then when your task finishes set it back to true. Simply override onPostExecute(...) and insertbtn_submit.setCLickable(true) inside. Any questions?

Sahar Avr
  • 131
  • 8