0

so I'm building this android app and I working on an error message that is to be displayed when a user entered a wrong username or password. The error message displays sporadically right now. I get an exception called

android.view.viewroot$calledfromwrongthreadexception

which when I researched only, the writers basically said that when you are using an AsyncTask, it's not a good idea to set the text in the doinBackground method. Since setting the test in onPostExecute would display the method at anytime whether the login was successful or not, the partial solution I came up with is this.

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class Login extends Activity {
    static EditText alog;
    static EditText apass;
    JSONParser jsnParser = new JSONParser();
    public static String url_login="...";
    private static final String TAG_SUCCESS = "operation";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent it =getIntent();
        setContentView(R.layout.activity_login);
         alog=(EditText)findViewById(R.id.loginuser);
         apass=(EditText)findViewById(R.id.loginpass);

          Button btnLogin = (Button)findViewById(R.id.loggin);
          Button btnRegister =(Button)findViewById(R.id.register2);

          btnRegister.setOnClickListener(new View.OnClickListener() {


                public void onClick(View view) {

                    Intent i=new Intent(Login.this, Registration.class);
                    startActivity(i);
                }
            });

          btnLogin.setOnClickListener(new View.OnClickListener() {


            public void onClick(View view) {

                new LoggerIn().execute();
            }
        });


    }
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.login, menu);
        return true;
    }

    class LoggerIn  extends AsyncTask<String, String, String> {

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

            String logger=alog.getText().toString();
            String passer=apass.getText().toString();



        List <NameValuePair> prm=new ArrayList<NameValuePair>();
        prm.add(new BasicNameValuePair("username", logger));
        prm.add(new BasicNameValuePair("password", passer));

        JSONObject jsn= jsnParser.makeHttpRequest(url_login, "POST", prm);


        Log.d("Create Response", jsn.toString());
        try {
            boolean success=jsn.getBoolean(TAG_SUCCESS);

            if (success == true) {
                // successfully created product
                Intent i = new Intent(getApplicationContext(), Home.class);

                startActivity(i);

                // closing this screen
                finish();
            } else {
                // failed to create product
                //onPostExecute
                //TextView txt=(TextView)findViewById(R.id.login_error);
                //txt.setText("The username or password you entered was wrong");
                displayError();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
        }

        protected void displayError() {
            // dismiss the dialog after getting all products

            // updating UI from Background Thread
            TextView txt=(TextView)findViewById(R.id.login_error);
            txt.setText("The username or password you entered was wrong");

        }
    }



}

However when I fail to login, I have to fail 2 or 3 repetitive times before the message appears. Is there a proper way to do this?

Shobhit Puri
  • 25,769
  • 11
  • 95
  • 124
Michael Nana
  • 1,969
  • 4
  • 24
  • 36

2 Answers2

2

The problem seems to be that you are trying to do something on the UI thread from within the AsyncTask. If you want to make changes the UI thread( i.e show Toast, set TextView etc), do it in onPostExecute() method or use you may also use runOnUiThread for making changes from within the doInBackground.

See the above question which further explains the error you are getting and how you may correct: How to fix android.os.NetworkOnMainThreadException?

See here how you can call methods on UI thread from within AsyncTask: Android : Calling the methods on UI thread from AsyncTask doInBackground method

Hope this helps.

Community
  • 1
  • 1
Shobhit Puri
  • 25,769
  • 11
  • 95
  • 124
  • Perfect. Thanks man, runOnUiThread was the option I used and it worked. I need to wait for 4 more minutes before I can accept your answer though. ahaha. – Michael Nana Jul 16 '13 at 00:29
0

You can only update the UI from the UI thread. Do all UI calls in your Asynctask from a method that has access to the UI thread, that would be onPreExecute(), onProgressUpdate() and onPostExecute().

Ahmad
  • 69,608
  • 17
  • 111
  • 137