Mike
Mike

Reputation: 1312

AsyncTask process

I am creating an app, when you log in with user name and password, it requests the info from the server. The server's request takes time (15-20 sec), meanwhile I want to show a spinning bar with few words. But I tried so many variations of the AsyncTask class, and I can't get it to work. It gets the information okay, but freezes the screen until the response. Right now I just have a new thread implementing runnable. I'm not sure from where in the code I need to call the AsyncTask .

The onClick triggers the attemptLogin() function:

    public void onClick(View view) {
        attemptLogin();
    }

In attemptLogin() function:

// more code
showProgress(true);
new Thread(new GetServerResponseRunnable()).start();
while (wait) {}
// more code

And the Runnable is:

public class GetServerResponseRunnable implements Runnable {
    @Override
    public void run() {
        response = getInfo.getTours(mUsername, mPassword);
        wait = false;   
    }       

}  

Which as you can see call another function from a different class. This is the function:

public String getTours(String username, String password) {
    String req = "GETALLDATA";
    String retStr = "";
    try {
        url = getURL(req, username, password);
        sendOutputLine(url, "");
        retStr = getReturnString();
        Log.d(LoginActivity.DEBUG_TAG, "getTours() return: " + retStr);
    } catch (Exception e) {
        Log.d(LoginActivity.DEBUG_TAG, "programm bommed client: " + e.getMessage());
    }
    return retStr;
}   

I need help, please. Mainly what I want to do is:

    response = getInfo.getTours(mUsername, mPassword);
    wait = false;

And show the spinning bar meanwhile.

Thanks


Update: 02.13.2013

I used this code, but I got a

02-13 09:07:16.142: E/AndroidRuntime(1046): java.lang.NullPointerException

in the line:

this.dialog.setMessage(getResources().getString(R.string.login_progress_signing_in));

Any idea why?

public class LoginTask extends AsyncTask<Object, Void, String> {

    public Context context;
    public ProgressDialog dialog;


    public void BaseTask(Context context) {
        this.context = context;
        this.dialog = new ProgressDialog(context);
    }

    @Override
    protected void onPreExecute() {
        this.dialog.setMessage(getResources().getString(R.string.login_progress_signing_in));
        this.dialog.show();

    }

    @Override
    protected String doInBackground(Object... objects) {
        String name = (String) objects[0];
        String password = (String) objects[1];
        String response = getInfo.getTours(name , password );
        return response;
    }

    @Override
    protected void onPostExecute(String response) {
        if (dialog != null && dialog.isShowing())
            dialog.dismiss();

        LoginActivity.response = response; 

        // process response as you need
    }
} 

Upvotes: 0

Views: 761

Answers (4)

Georgy Gobozov
Georgy Gobozov

Reputation: 13721

I think you need thomething like this

public class LoginTask extends AsyncTask<Object, Void, String> {

    public Context context;
    public ProgressDialog dialog;


    public BaseTask(Context context) {
        this.context = context;
        this.dialog = new ProgressDialog(context);
    }

    @Override
    protected void onPreExecute() {
        this.dialog.setMessage(context.getResources().getString(R.string.loading));
        this.dialog.show();

    }

    @Override
    protected String doInBackground(Object... objects) {
        String name = (String) objects[0];
        String password = (String) objects[1];
        String response = getInfo.getTours(name , password );
        return response;
    }

    @Override
    protected void onPostExecute(String response) {
        if (dialog != null && dialog.isShowing())
            dialog.dismiss();

        // process response as you need
    }
}

Call this taks

public void onClick(View view) {
    new LoginTask(YourActivity.this).execute(name, password);
}

Upvotes: 1

FoamyGuy
FoamyGuy

Reputation: 46846

Your AsyncTask might look something like this:

 private class DownloadFilesTask extends AsyncTask<Login, Void, Tours> {
     protected void onPreExecute(){
        //show the dialog here
     }

     protected Long doInBackground(URL... urls) {
         Tours response = getInfo.getTours(Login.mUsername, Login.mPassword);
         return response;
     }


     protected void onPostExecute(Long result) {
         //hide the dialog here
     }
 }

I don't know enough about your project to make it be a drop in, you'll have to customize it a bit, but the overall "way" will be similar to this.

Upvotes: 0

Matt K
Matt K

Reputation: 6709

You need to implement a new class that extends AsyncTask, do all of the extensive work inside a function called doInBackground, and publish the results to the UI thread using some other common methods like onProgressUpdate. A quick web search for "android asynctask tutorial" will yield some good results for you to learn from.

Upvotes: 0

Quantico
Quantico

Reputation: 2436

Try to implement android login activity. In your ADT under create new activity pick: login activity This will generate the following template code for you:

/**
 * Activity which displays a login screen to the user, offering registration as
 * well.
 */
public class LoginActivityTest extends Activity {
    /**
     * A dummy authentication store containing known user names and passwords.
     * TODO: remove after connecting to a real authentication system.
     */
    private static final String[] DUMMY_CREDENTIALS = new String[] {
            "[email protected]:hello", "[email protected]:world" };

    /**

         * The default email to populate the email field with.
         */
        public static final String EXTRA_EMAIL = "com.example.android.authenticatordemo.extra.EMAIL";

        /**
         * Keep track of the login task to ensure we can cancel it if requested.
         */
        private UserLoginTask mAuthTask = null;

        // Values for email and password at the time of the login attempt.
        private String mEmail;
        private String mPassword;

        // UI references.
        private EditText mEmailView;
        private EditText mPasswordView;
        private View mLoginFormView;
        private View mLoginStatusView;
        private TextView mLoginStatusMessageView;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_login_activity_test);

            // Set up the login form.
            mEmail = getIntent().getStringExtra(EXTRA_EMAIL);
            mEmailView = (EditText) findViewById(R.id.email);
            mEmailView.setText(mEmail);

            mPasswordView = (EditText) findViewById(R.id.password);
            mPasswordView
                    .setOnEditorActionListener(new TextView.OnEditorActionListener() {
                        @Override
                        public boolean onEditorAction(TextView textView, int id,
                                KeyEvent keyEvent) {
                            if (id == R.id.login || id == EditorInfo.IME_NULL) {
                                attemptLogin();
                                return true;
                            }
                            return false;
                        }
                    });

            mLoginFormView = findViewById(R.id.login_form);
            mLoginStatusView = findViewById(R.id.login_status);
            mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);

            findViewById(R.id.sign_in_button).setOnClickListener(
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            attemptLogin();
                        }
                    });
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            super.onCreateOptionsMenu(menu);
            getMenuInflater().inflate(R.menu.activity_login_activity_test, menu);
            return true;
        }

        /**
         * Attempts to sign in or register the account specified by the login form.
         * If there are form errors (invalid email, missing fields, etc.), the
         * errors are presented and no actual login attempt is made.
         */
        public void attemptLogin() {
            if (mAuthTask != null) {
                return;
            }

            // Reset errors.
            mEmailView.setError(null);
            mPasswordView.setError(null);

            // Store values at the time of the login attempt.
            mEmail = mEmailView.getText().toString();
            mPassword = mPasswordView.getText().toString();

            boolean cancel = false;
            View focusView = null;

            // Check for a valid password.
            if (TextUtils.isEmpty(mPassword)) {
                mPasswordView.setError(getString(R.string.error_field_required));
                focusView = mPasswordView;
                cancel = true;
            } else if (mPassword.length() < 4) {
                mPasswordView.setError(getString(R.string.error_invalid_password));
                focusView = mPasswordView;
                cancel = true;
            }

            // Check for a valid email address.
            if (TextUtils.isEmpty(mEmail)) {
                mEmailView.setError(getString(R.string.error_field_required));
                focusView = mEmailView;
                cancel = true;
            } else if (!mEmail.contains("@")) {
                mEmailView.setError(getString(R.string.error_invalid_email));
                focusView = mEmailView;
                cancel = true;
            }

            if (cancel) {
                // There was an error; don't attempt login and focus the first
                // form field with an error.
                focusView.requestFocus();
            } else {
                // Show a progress spinner, and kick off a background task to
                // perform the user login attempt.
                mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
                showProgress(true);
                mAuthTask = new UserLoginTask();
                mAuthTask.execute((Void) null);
            }
        }

        /**
         * Shows the progress UI and hides the login form.
         */
        @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
        private void showProgress(final boolean show) {
            // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
            // for very easy animations. If available, use these APIs to fade-in
            // the progress spinner.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
                int shortAnimTime = getResources().getInteger(
                        android.R.integer.config_shortAnimTime);

                mLoginStatusView.setVisibility(View.VISIBLE);
                mLoginStatusView.animate().setDuration(shortAnimTime)
                        .alpha(show ? 1 : 0)
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                mLoginStatusView.setVisibility(show ? View.VISIBLE
                                        : View.GONE);
                            }
                        });

                mLoginFormView.setVisibility(View.VISIBLE);
                mLoginFormView.animate().setDuration(shortAnimTime)
                        .alpha(show ? 0 : 1)
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                mLoginFormView.setVisibility(show ? View.GONE
                                        : View.VISIBLE);
                            }
                        });
            } else {
                // The ViewPropertyAnimator APIs are not available, so simply show
                // and hide the relevant UI components.
                mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
                mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
            }
        }

        /**
         * Represents an asynchronous login/registration task used to authenticate
         * the user.
         */
        public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
            @Override
            protected Boolean doInBackground(Void... params) {
                // TODO: attempt authentication against a network service.

                try {
                    // Simulate network access.
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    return false;
                }

                for (String credential : DUMMY_CREDENTIALS) {
                    String[] pieces = credential.split(":");
                    if (pieces[0].equals(mEmail)) {
                        // Account exists, return true if the password matches.
                        return pieces[1].equals(mPassword);
                    }
                }

                // TODO: register the new account here.
                return true;
            }

            @Override
            protected void onPostExecute(final Boolean success) {
                mAuthTask = null;
                showProgress(false);

                if (success) {
                    finish();
                } else {
                    mPasswordView
                            .setError(getString(R.string.error_incorrect_password));
                    mPasswordView.requestFocus();
                }
            }

            @Override
            protected void onCancelled() {
                mAuthTask = null;
                showProgress(false);
            }
        }
    }

The UserLoginTask is where you want to do your authentication. This will allow you to show a spinner while you are trying to login. The 'onPostExecute' will be the place where you either move to your next activity upon verification, or go back to the login screen with a message for the user, for example invalid password.

Please note that the template includes dummy_credentials that you don't need if you are authenticating with a server, and that it comes with email and password textEdits, but you can change those to anything you want.

Upvotes: 0

Related Questions