androidandroid-viewandroid-progressbar

How can I force a blocking redraw of a UI element?


I have a simple login page where the user enters a password, and that password is used to decrypt some data and create the main activity. The process of generating the key, calling the database and creating the main activity takes about 5 seconds so I want to show a progress wheel on the login screen immediately after the user clicks the login button.

Unfortunately since android handles UI refreshes in a non-blocking way the progress bar won't appear before the login function runs. I can't seem to find a way to force a blocking UI refresh for a view in Android. invalidate() and postInvalidate() both won't work since these simply notify Android that a redraw should happen at some point in the future.

Here is some sample code to explain what I'm trying to accomplish:

        try {
            progressBar.setVisibility(View.VISIBLE);
            passwordEditText.setEnabled(false);

            Key key = doLogin(passwordEditText.getText()); // Long operation

            Intent intent = new Intent(getActivity(), MainActivity.class);
            intent.putExtra("Key", key);
            startActivity(intent);

            getActivity().finish();

        } catch (Exception e) {
            passwordEditText.setError(getString(R.string.login_error));
            Log.e("Login", e.getMessage());
        } finally {
            progressBar.setVisibility(View.INVISIBLE);
            passwordEditText.setEnabled(true);
        }

If it's not possible to override the default behaviour and force an immediate blocking redraw, then how best can I best implement a progress wheel while the doLogin() method runs?


Solution

  • I can't seem to find a way to force a blocking UI refresh for a view in Android

    Correct. That is not how the Android view system works.

    then how best can I best implement a progress wheel while the doLogin() method runs?

    Have doLogin() be performed on a background thread. Update the UI on the main application thread when the background work finishes. Take into account that your UI may no longer exist (e.g., user pressed BACK) or may be replaced (e.g., user rotated the device or otherwise triggered a configuration change) while that background work is going on.

    In modern Android app development, the three main approaches for doing this are to use a ViewModel and LiveData along with: