无法在未调用 Looper.prepare() 的线程内创建处理程序 - Google

Can't create handler inside thread that has not called Looper.prepare() - Google Translate

您好,当我点击按钮中的翻译时,我正在尝试使用 google 翻译 api 来翻译字符串。当我 运行 作为 AVD 它工作正常时,问题是当我尝试使用我的智能手机进行部署时,当我单击翻译按钮时应用程序关闭并且我收到错误消息。

Bundle bundle = getIntent().getExtras();
    String word = "";
    if(bundle.containsKey("Name")){
        word = (String) bundle.getString("Name");
        txtTarget.setText(word);
        //envia para o translate api para traduzir a palavra pro portugues
    }

    final String finalWord = word;
    btnResultado.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            final Handler textViewHandler = new Handler();

            new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... params) {

                    Translate translate = TranslateOptions.newBuilder().setApiKey(API_KEY).build().getService();

                    final Translation translation = translate.translate(finalWord, Translate.TranslateOption.targetLanguage("pt"));

                    textViewHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            txtSource.setText(translation.getTranslatedText());
                        }
                    });
                    return null;
                }
            }.execute();
        }
    });

错误:

Process: com.google.sample.cloudvision, PID: 8874 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask.done(AsyncTask.java:309) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.(Handler.java:200) at android.os.Handler.(Handler.java:114) at android.widget.Toast$TN.(Toast.java:345) at android.widget.Toast.(Toast.java:101) at android.widget.Toast.makeText(Toast.java:259) at com.google.sample.cloudvision.ActSegundaTela.doInBackground(ActSegundaTela.java:82) at com.google.sample.cloudvision.ActSegundaTela.doInBackground(ActSegundaTela.java:79) at android.os.AsyncTask.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)

您不需要创建新的处理程序。您可以使用任何视图作为处理程序。

txtSource.post(new Runnable() {
    public void run(){
        txtSource.setText(...
    }
});

如果你真的要创建一个Handler,那么按照报错信息中提到的,在doInBackground的第一行调用Looper.prepare();,在最后一行调用Looper.loop()

doInBackground(){
    Looper.prepare();
    //your code
    Lopper.loop();
}

如果您的代码在 activity 中或具有 activity 的引用,您可以使用方法 runOnUiThread[= 直接在 UI 线程中执行操作16=]

不确定具体是哪一行,但从 Exception 来看,您的 doInBackground() 方法中的一个方法似乎正在尝试显示 Toast。尝试从后台线程显示 Views 是不行的,这就是导致崩溃的原因。

您可以将块包裹在 try { } catch(Exception e) { ... } 中以识别试图显示 Toast 的行 - 因为该部分可能应该从后台线程中拉出以防止 Exception.