无法在未调用 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
。尝试从后台线程显示 View
s 是不行的,这就是导致崩溃的原因。
您可以将块包裹在 try { } catch(Exception e) { ... }
中以识别试图显示 Toast
的行 - 因为该部分可能应该从后台线程中拉出以防止 Exception
.
您好,当我点击按钮中的翻译时,我正在尝试使用 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
。尝试从后台线程显示 View
s 是不行的,这就是导致崩溃的原因。
您可以将块包裹在 try { } catch(Exception e) { ... }
中以识别试图显示 Toast
的行 - 因为该部分可能应该从后台线程中拉出以防止 Exception
.