简体   繁体   中英

How to make a Main Thread waiting for the AsyncTask android, without blocking the UI

I am trying to make login view. I' d like to start a new AsyncTask that performs the REST call to the server and shows a progress bar . I need that the UI main thread wouldn't block and it must show a toast with message (like success or fail) depending on what the AsyncTask returns .

Here the code:

SetupActivity (main thread):

//Get reference SignUp Button
    Button signupButton = (Button)myDialog.findViewById(R.id.button_signup_OK);
    signupButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            //Get all the textfield content from the form
            name=((EditText)myDialog.findViewById(R.id.nameEditText)).getText();
            surname=((EditText)myDialog.findViewById(R.id.surnameEditText)).getText();
            email=((EditText)myDialog.findViewById(R.id.emailEditText)).getText();
            password=((EditText)myDialog.findViewById(R.id.passwordEditText)).getText();
            password_Retyped=((EditText)myDialog.findViewById(R.id.passwordRepEditText)).getText();

            //Get hash from password
            hashPassword=DigestMd5.md5(password);
            hashPasswordRep=DigestMd5.md5(password_Retyped);

            //Check if the fields are null
            if(name.toString().equals("")){
                ((EditText) myDialog.findViewById(R.id.nameEditText)).setError(getString(R.string.mandatoryField));
            }
            if(surname.toString().equals("")){
                ((EditText) myDialog.findViewById(R.id.surnameEditText)).setError(getString(R.string.mandatoryField));
            }
            if(email.toString().equals("") ){
                ((EditText) myDialog.findViewById(R.id.emailEditText)).setError(getString(R.string.mandatoryField));
            }else{
                if(!new EmailValidator().validate(email.toString())){
                    ((EditText)myDialog.findViewById(R.id.emailEditText)).setError(getString(R.string.emailWrong));
                }
            }
            if(password.toString().equals("")){
                ((EditText) myDialog.findViewById(R.id.passwordEditText)).setError(getString(R.string.mandatoryField));
            }
            if(password_Retyped.toString().equals("")){
                ((EditText) myDialog.findViewById(R.id.passwordRepEditText)).setError(getString(R.string.mandatoryField));
            }

            //Check match password
            if(!hashPassword.equals(hashPasswordRep)){
                ((EditText)myDialog.findViewById(R.id.passwordEditText)).setError(getString(R.string.passwordNotMatching));
                ((EditText)myDialog.findViewById(R.id.passwordRepEditText)).setError(getString(R.string.passwordNotMatching));
            }





                StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                StrictMode.setThreadPolicy(policy);

                try {

                    //Start AsyncTask
                    new loadingBar().execute().get();

                    Boolean resultOK = ackJSON.has("result");

                    if(resultOK){
                        //close dialog
                        myDialog.dismiss();

                        // Inflate the Layout
                        LayoutInflater inflater = getLayoutInflater();
                        View layout = inflater.inflate(R.layout.custom_toast_success,(ViewGroup) findViewById(R.id.custom_toast_layout_id));

                        Toast toastOK = new Toast(getApplicationContext());
                        toastOK.setDuration(Toast.LENGTH_LONG);
                        toastOK.setView(layout);
                        toastOK.show();

                    }else{
                        //Feedback both using Toasts and textedit
                        ((EditText) myDialog.findViewById(R.id.emailEditText)).setError(getString(R.string.userAlreadyIn));

                        // Inflate the Layout
                        LayoutInflater inflater = getLayoutInflater();
                        View layout = inflater.inflate(R.layout.custom_toast_erroruser,(ViewGroup) findViewById(R.id.custom_toast_no_user));

                        Toast toastNoUser = new Toast(getApplicationContext());
                        toastNoUser.setDuration(Toast.LENGTH_SHORT);
                        toastNoUser.setGravity(Gravity.TOP,0,50);
                        toastNoUser.setView(layout);
                        toastNoUser.show();

                    }

                } catch (IOException e) {
                    // Inflate the Layout
                    LayoutInflater inflater = getLayoutInflater();
                    View layout = inflater.inflate(R.layout.custom_toast_errorconnection,(ViewGroup) findViewById(R.id.custom_toast_no_noConn));

                    Toast toastNoConn = new Toast(getApplicationContext());
                    toastNoConn.setDuration(Toast.LENGTH_SHORT);
                    toastNoConn.setGravity(Gravity.TOP,0,50);
                    toastNoConn.setView(layout);
                    toastNoConn.show();
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }

        }
    });
}

class loadingBar extends AsyncTask<Void,Integer,JSONObject>{

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progress.setProgress(0);
        progress.show();
    }

    @Override
    protected JSONObject doInBackground(Void... arg0)
    {
        ackJSON = null;
        try
        {
            for(int i=0;i<2;i++)
            {
                publishProgress(new Integer[]{i*10});
                Thread.sleep(1200);
            }
            String ack=HTTPRest.putNewUser(name.toString(),surname.toString(),email.toString(),hashPassword);
            ackJSON=new JSONObject(ack);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return ackJSON;
    }

    @Override
    protected void onProgressUpdate(Integer... values)
    {
        super.onProgressUpdate(values);
        progress.setProgress(values[0].intValue());
    }

    @Override
    protected void onPostExecute(JSONObject result)
    {
        super.onPostExecute(result);
        progress.dismiss();
        ackJSON=result;
    }
}

Please let me know for any error in code

Thank you

All is correct but you will change for this code

  if(name.toString().isEmpty()){

        } 

because your code is some time problem when you not enter any value then not check your condition. Your code will check only black space.

btnLogin.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                String email = inputEmail.getText().toString();
                String password = inputPassword.getText().toString();

                // Check for empty data in the form
                if (email.trim().length() > 0 && password.trim().length() > 0) {
                    // login user
                    //checkLogin(email, password);
                    new AttemptLogin().execute();
                } else {
                    // Prompt user to enter credentials
                    Toast.makeText(getApplicationContext(),
                            "Please enter the credentials!", Toast.LENGTH_LONG)
                            .show();
                }
            }
        });

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


        /** * Before starting background thread Show Progress Dialog * */

        boolean failure = false;

        @Override protected void onPreExecute() { 
            super.onPreExecute(); 
            pDialog = new ProgressDialog(LoginActivity.this); 
            pDialog.setMessage("Attempting for login..."); 
            pDialog.setIndeterminate(false); 
            pDialog.setCancelable(true); 
            pDialog.show(); 

        }

        @SuppressWarnings("deprecation")
        @Override
        protected String doInBackground(String... args) {
            // TODO Auto-generated method stub
            // here Check for success tag

            int success; 
            String username = inputEmail.getText().toString(); 
            String password = inputPassword.getText().toString(); 

            try {

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

                Log.d("request!", "starting");

                JSONObject json = jsonParser.makeHttpRequest(AppConfig.URL_LOGIN, "POST", params);

                // checking  log for json response
                //devraj......................
                Log.d("Login attempt", json.toString());

                 // success tag for json
                success = json.getInt(TAG_SUCCESS);



                 if (success == 1){

                     session.setLogin(true);

                     Log.d("Successfully Login!", json.toString());

                     Intent intent = new Intent(LoginActivity.this,Secondpage.class);

                     startActivity(intent);



                     return json.getString(TAG_MESSAGE);

            }
            else{
                return json.getString(TAG_MESSAGE);
              }
        }
            catch (JSONException e){

                e.printStackTrace();
            }

            return null;
        }

        /** * Once the background process is done we need to Dismiss the progress dialog asap * **/

        protected void onPostExecute(String message)
        {

            pDialog.dismiss();

            if (message != null){

                 Toast.makeText(First.this, message, Toast.LENGTH_LONG).show();
            }
        }
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }

You can show Toast in your onPostExecute() method

The lifecycle of Asynktask is runs like this

onPreExecute() -> runs first

doInBackground() -> After onPreExecute 

and

`onPostExecute()` -> After doInBackground

So you can update UI or show Toast in onPostExecute()

You can do your work inside onPostExecute method of AsyncTask

    @Override
        protected void onPostExecute(JSONObject result)
        {
            super.onPostExecute(result);
            progress.dismiss();
            ackJSON=result;

            //do your work here show toast or move to next activity
        }
progress.setCancelable(false);

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