简体   繁体   中英

TextView doesn't change to the new setted text

I've an Android app that has a login capabilities, and the login box has a TextView that displays messages to the user when trying to login(ie. wrong name, wrong pass, etc..).

I have two methods, the first one check if the fields is filled or not, and if filled it redirects the app to the second method that will check the user/pass from the local server. the problem is when resetting the text in the second method, as when i set the text at the first method everything is OK, but when changing it in the second method it doesn't change, I can set it like million times in the first method and everything going well, another thing is when i set the text at the first time from the second method it works perfectly.

Hint1 : this first method is the onClick method of an OnClickListener . Hint2 : the printed log is prented like million times in the logcat so the while condition verified

public class Login extends Activity {

public EditText user, pw;
public TextView errorMessage;
private static String response = null;
private static String data;

the first method :

public void onClick(View v) {

            if (v == login) {

                String userName = Login.this.user.getText().toString();
                String Password = Login.this.pw.getText().toString();

                if (userName.equals(null_string)
                        || Password.equals(null_string)) {
                    errorMessage.setText(R.string.request);
                } else {
                    protocol = protocol_login;

                    boolean status = false;
                    try {
                        status = checkLogin(userName, Password);
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                    }

                    if (status) {
                        Intent intent = new Intent(v.getContext(),
                                MainPage.class);
                        go(intent);
                    } else {
                        errorMessage.setText(R.string.login_error);
                    }
                }
            }

        }

the second method:

private String connect(String data) throws UnknownHostException,
        IOException, JSONException {

    setData(data);
    Thread connect = new Thread(new ConnectToServer(getData()));
    connect.start();
    while (response == null) {
        System.out.println("waiting");
        errorMessage.setText(R.string.waiting);
    }
    return response;

}
}

Your problem lies in the fact that in the second method you are trying to update the GUI while actually being a second thread.

U can use the runOnUIThread method

Activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
           errorMessage.setText(R.string.waiting);
        }
});
while (response == null) {
    System.out.println("waiting");  
}

U also shouldn't set the text in a while-loop if the text isn't changing so you don't use unnecessary resources.

I'm not sure what exactly is causing your problem (you are blocking the UI thread somewhere), but there are better ways of getting a response from the server. You are essentially synchronously checking for an asynchronous response (below), because you are continuously polling whether response is not null.

Android has a useful class called AsyncTask . You give an AsyncTask some work to do on a background thread (what ConnectToServer(..) does), and when it is done, another method on the AsyncTask (called onPostExecute(..) ) is called. The benefit of this over your approach is that it handles all the threading for you, and doesn't poll. There is also a method onPreExecute() which you would set your waiting text in.

NB checking synchronously for an asynchronous response

What I mean by this is that the response can come back at any time (asynchronously), yet you are checking for it at any point you can (synchronously). This is going to waste valuable resources on the CPU - you should get the response to tell you when it is finished rather than continually ask whether it is.

First, these two string variables are declared globally:

String userName,Password

Try this easy Asyntask method:

    private class SetDataOfWebService extends AsyncTask<Void, Void,Boolean> {
            ProgressDialog pDialog;
            boolean success = false;
            ConnectivityManager connectivity;

            @Override
            protected void onPreExecute() {
                pDialog = new ProgressDialog(MailSettings.this);
                pDialog.setMessage("Please Wait..");
                pDialog.show();
            }

            @Override
            protected Boolean doInBackground(Void... params) {
                if (isNetworkAvailable()) {
                    success = true;

                      if (userName.length()>0 || Password.length()>0) {
                           status = checkLogin(userName, Password);
                      }
                      else
                      {
                          errorMessage.setText(R.string.request);
                      }
                } else {
                    success = false;
                }
                return success;
            }

            @Override
            protected void onPostExecute(Boolean result) {
                if (pDialog != null && pDialog.isShowing())
                    pDialog.dismiss();
                if (result) {
                    if (status) {
                            Intent intent = new Intent(v.getContext(),
                                    MainPage.class);
                            go(intent);
                        } else {
                            errorMessage.setText(R.string.login_error);
                        }
                } else {
                    return;
                }

            }

            public boolean isNetworkAvailable() {
                connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

                if (connectivity != null) {
                    NetworkInfo[] info = connectivity.getAllNetworkInfo();

                    if (info != null) {
                        for (int i = 0; i < info.length; i++) {
                            Log.i("Class", info[i].getState().toString());
                            if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }

    }

////Calling This Function On Button CLick Like This
userName = Login.this.user.getText().toString();
Password = Login.this.pw.getText().toString();
new SetDataOfWebService().execute();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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