Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onPrepareOptionsMenu acts weird if API is called from inside

I have a need to enable and disable menu items based on the API call response and it has to be called everytime the menu shows up.

I need asynctask because I have to show progressbar

    @Override
    public boolean onPrepareOptionsMenu (Menu menu) {
       handleMenuItems(menu)

     }

    private void handleMenuItems(menu)
    {


        new AsyncTask<Void, Void, Void>(){

            @Override
            protected Void doInBackground(Void... params) {
                //API call                  
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);
                if (progressDialog != null)
                    progressDialog.hide();

                               //necessary menu items are enabled and disabled
                                super.onPrepareOptionsMenu(menu);
            }

            @Override
            protected void onPreExecute() {
                if (progressDialog != null){
                    progressDialog.setMessage("Checking");
                    progressDialog.show();
                }
                super.onPreExecute();
            }

        }.execute();

    }

Whenever I touch the options menu the onPrepareOptionsMenu gets called and the options menu doesn't appear then when I press it again the onPrepareOptionsMenu doesn't get called and the options menu appears.

I want the api to get called every time and menu to be shown whenever I touch for options menu.

like image 804
Venky Avatar asked Jul 21 '14 16:07

Venky


2 Answers

You shouldn't show and hide progress dialog in OnPrepareOptionsMenu

Comment out the progress dialog codings and rest of the codes are ok and works as you expected

Note:

  • You have called super.OnPrepareOptionsMenu in OnPostExecute(UI Thread)

  • As the progress bar is not needed don't remove the AsyncTask otherwise app my crash

like image 195
Shajo Avatar answered Nov 16 '22 11:11

Shajo


I don't think this code does what you expect it to do. When onPrepareOptionsMenu is called the first time, it only schedules the AsyncTask to run at a future time and not right away. Next it executes the super.onPrepareOptionsMenu line which should show whatever the option menu is set to be at that time. I think (have to check on that) the UI will then wait for the user input as it is showing some sort of a menu (maybe not what you had expected). When the menu is touched for the second time, I think it will dismiss the menu and that might be the time that the AsyncTask is executed which results in the first menu that you had expected in the first place. The second instance of the AsyncTask will not run until the first one finishes (unless executeOnExecutor is called instead of execute, but that is not the case here nor I believe it to help the expected outcome.)

You might want to have a "dummy" menu prepared (maybe something that shows "waiting...") and start a background thread where it builds up the right menu and then when it is ready update and display a new menu (programmatically).

I personally would advise in finding a way to build and show the menu on the UI thread (maybe prep the menu as the changes are made, ahead of time, and just show it when needed.

Kaamel

like image 20
Kaamel Avatar answered Nov 16 '22 12:11

Kaamel