0

在过去 3 周左右的时间里,我一直在学习 Android 编程,我正在开发一个应用程序,该应用程序使用 EditText 获取用户的结果,并使用 Microsoft Translate API 将其翻译成用户选择的语言。

我面临的问题是我无法让应用程序让用户从菜单中选择一种语言,然后翻译 EditText 框中给出的文本。这个问题是由于我对 AsyncTask 不熟悉,我试图在不使用它的情况下运行应用程序,但它会返回 e 异常。但是,当我选择一种默认语言时,它确实有效,如以下代码所示

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;
    }   
}

任何帮助,将不胜感激

这是完整的代码。

文件

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;
    }   
}
4

1 回答 1

0

您无法从后台线程访问 ui 方法(例如启动弹出菜单)。

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);
于 2013-03-30T08:45:44.810 回答