Search code examples
javaandroidapitranslate

How to Call PopupMenu item in AsyncTask


I've been learning Android programming for the last 3 weeks or so and I'm developing an app that takes the user's result using an EditText and Translating it to the user's language of choice using Microsoft Translate API.

the Problem I'm facing is i couldn't get the application to let the user select a language from the menu and then translate the text given in the EditText box. This problem is due to my unfamiliarity with AsyncTask, i tried to run the application without using it but it would return the e exception. It does work however when i select one default language as shown in the following code

class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
    @Override
    protected Boolean doInBackground(Void... arg0) {
        Translate.setClientId("MicrosoftTranslatorJavaAPI");
        Translate.setClientSecret(secret_key);


        try {
            translatedText = Translate.execute(et.getText().toString(), Language.ENGLISH, Language.FRENCH);
        } catch(Exception e) {
            translatedText = e.toString();
        }
        return true;
    }   
}

Any help would be appreciated

Here is the full code.

java file

public class MicrosoftTranslatorAndroidTestActivity extends Activity {
    /** Called when the activity is first created. */
    TextView text;
    String translatedText;
    EditText et;
    PopupMenu popupMenu;


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

        setContentView(R.layout.main);
        et=(EditText) findViewById(R.id.editText1);
        Button b=(Button) findViewById(R.id.button1);

        text = (TextView) findViewById(R.id.tv1);
        text.setText("<This text should change after translation has occurred in AsyncTask>");
        b.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                  popupMenu = new PopupMenu(MicrosoftTranslatorAndroidTestActivity.this, v);
                  popupMenu.getMenuInflater().inflate(R.menu.popmenu, popupMenu.getMenu());  
                new MyAsyncTask() { 
                    protected void onPostExecute(Boolean result) {
                        text.setText(translatedText);
                    }
                }.execute();
                popupMenu.show();
            }
        });



}

class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
    @Override
    protected Boolean doInBackground(Void... arg0) {
        Translate.setClientId("MicrosoftTranslatorJavaAPI");
        Translate.setClientSecret(secret_key);

        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {

            public boolean onMenuItemClick(MenuItem item) {
                // TODO Auto-generated method stub
                switch (item.getItemId()){

                case R.id.ar:

                    try {
                        translatedText = Translate.execute(et.getText().toString(), Language.ENGLISH, Language.ARABIC);
                    } catch(Exception e) {
                        translatedText = e.toString();
                    }

                    break;

                case R.id.fr:

                    try {
                        translatedText = Translate.execute(et.getText().toString(), Language.ENGLISH, Language.FRENCH);
                    } catch(Exception e) {
                        translatedText = e.toString();
                    }

                    break;

                case R.id.sp:

                    try {
                        translatedText = Translate.execute(et.getText().toString(), Language.ENGLISH, Language.SPANISH);
                    } catch(Exception e) {
                        translatedText = e.toString();
                    }

                    break;
                    default:
                    break;


                }


                return true;
            }
        });


        return true;
    }   
}

Solution

  • You can't access ui methods (such as launching a popup menu) from a background thread.

    What's more, that would result in having your popup shown but the runInBackgroundMethod would finish in any case and your translate.execute would not be called.

    You have to decouple the asyncrhonous interaction with translate from the interactions with the ui elements. Assuming that you need to perform the Translate.execute() method in a background thread, what you should do is to fetch the parameters of the translation BEFORE launching the backgound thread and fetch the results in your asyncthread's onPostExecute().

    Something like

    private class TranslateTask extends AsyncTask<String, Void, String> {
         protected void onProgressUpdate() {
    
         }
    
         protected void onPostExecute(String... result) {
             String translated = result[0];
         }
    
        @Override
        protected String doInBackground(String... params) {
            String toTranslate = params[0];
            String language = params[1];
                    // translate here and return the result
                    return translated;
                }
     }
    

    and then call

     translateTask.execute(toTranslate, language);