Как отобразить Toast в Android AsyncTask?
Я пытаюсь отобразить Toast в моем классе initial_background, расширенном с помощью AsyncTask<URL, Integer, Long>
. Я получаю эту ошибку в logcat.
public class InitialBackgroundTask extends AsyncTask<URL, Integer, Long> {
@Override
protected Long doInBackground(URL... params) {
// TODO Auto-generated method stub
show a = new show();
a.loop();
return null;
}
public class show {
void loop()
{
for(int i=0; i<10; i++)
{
Toast.makeText(MainActivity.me, "test", Toast.LENGTH_LONG).show();
}
}
}
05-30 12:08:12.641: E/AndroidRuntime(30840): FATAL EXCEPTION: AsyncTask #1
05-30 12:08:12.641: E/AndroidRuntime(30840): java.lang.RuntimeException: An error occured while executing doInBackground()
05-30 12:08:12.641: E/AndroidRuntime(30840): at android.os.AsyncTask$3.done(AsyncTask.java:278)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-30 12:08:12.641: E/AndroidRuntime(30840): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.lang.Thread.run(Thread.java:856)
05-30 12:08:12.641: E/AndroidRuntime(30840): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-30 12:08:12.641: E/AndroidRuntime(30840): at android.os.Handler.<init>(Handler.java:121)
05-30 12:08:12.641: E/AndroidRuntime(30840): at android.widget.Toast$TN.<init>(Toast.java:317)
05-30 12:08:12.641: E/AndroidRuntime(30840): at android.widget.Toast.<init>(Toast.java:91)
05-30 12:08:12.641: E/AndroidRuntime(30840): at android.widget.Toast.makeText(Toast.java:233)
05-30 12:08:12.641: E/AndroidRuntime(30840): at com.example.toast.show.loop(show.java:11)
05-30 12:08:12.641: E/AndroidRuntime(30840): at com.example.toast.InitialBackgroundTask.doInBackground(InitialBackgroundTask.java:13)
05-30 12:08:12.641: E/AndroidRuntime(30840): at com.example.toast.InitialBackgroundTask.doInBackground(InitialBackgroundTask.java:1)
05-30 12:08:12.641: E/AndroidRuntime(30840): at android.os.AsyncTask$2.call(AsyncTask.java:264)
05-30 12:08:12.641: E/AndroidRuntime(30840): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-30 12:08:12.641: E/AndroidRuntime(30840): ... 5 more
Вышеприведенный код показывает всю историю. На самом деле, я хочу показать тост в методе doInBackground
Ответы
Ответ 1
Вы не можете обновить ui в фоновом потоке. doonBAckground вызывается в фоновом потоке. Вы должны обновить ui в потоке ui.
runOnUiThread(new Runnable(){
@Override
public void run(){
//update ui here
// display toast here
}
});
onPreExecute(), onPostExecute (Result), вызывается в потоке ui. Таким образом, вы можете отображать тосты здесь.
onProgressUpdate (Прогресс...), вызывается в потоке пользовательского интерфейса после вызова publishProgress (Прогресс...). может использоваться для анимации индикатора выполнения или отображения журналов в текстовом поле.
Результат вычисления doInbackground() является параметром onPostExecute (Result), поэтому возвращаем результат в doinBackground() и показываем ваш тост в onPostExecute (результат)
Вы также можете использовать обработчик, предложенный @Stine Pike
Для ясности проверьте ссылку ниже в разделе "4 шага".
http://developer.android.com/reference/android/os/AsyncTask.html
Ответ 2
Создайте объект-обработчик и выполните все ваши сообщения Toast, используя это.
@Override
protected Void doInBackground(Void... params) {
Handler handler = new Handler(context.getMainLooper());
handler.post( new Runnable(){
public void run(){
Toast.makeText(context, "Created a server socket",Toast.LENGTH_LONG).show();
}
});
}
Ответ 3
Это другой способ, который не упоминается здесь следующим образом:
Шаг 1: Определите Обработчик как глобальный
Handler handler;
Шаг 2: Обработчик инициализации в doInBackground() следующим образом:
@Override
protected Void doInBackground(Void... params) {
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
//your code
}
}
};
}
Шаг 3: И теперь вы можете вызвать этот обработчик где угодно в коде, вызвав
if(handler != null){
handler.sendEmptyMessage(1);
}
Что еще вы можете сделать, так это отправить данные через обработчик следующим образом:
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putInt("KEY", value);
message.setData(bundle);
handler.sendMessage(message);
И обрабатывайте данные в вашем обработчике ниже
handler = new Handler(){
@Override
public void handleMessage(Message message) {
Bundle bundle = message.getData();
Integer value = bundle.getInt("KEY");
}
};
Ответ 4
покажите ваш Toast в onPostExecute или onPreExecute. doInBackGround работает в отдельном потоке, но два других метода запускаются в потоке пользовательского интерфейса.
Но если вам нужно показать тост в doInBackGround, вы можете использовать Handler.post или runonUiThread для показа тостов.
Ответ 5
Вы не можете отображать Toast в потоке non-ui (т.е. делать в фоновом режиме). Вы можете попробовать концепцию флага.
public class HttpRequest extends AsyncTask<String[], Void, String> {
boolean flag=false;
....
...
....
@Override
protected String doInBackground(String[]... params) {
//set flag as true when you need to trigger the Toast
try{
//Some Network Calls
} catch (HttpHostConnectException e) {
flag=true;
//Triggered Flas when i got Exceptions
}
}
@Override
protected void onPostExecute(String result) {
if(flag){
Toast.makeText(activity, "HttpHostConnectException Occured ", Toast.LENGTH_SHORT).show();
}
}
Счастливое кодирование..!!! введите код здесь
Ответ 6
Вы пытаетесь отобразить тост в потоке, отличном от ui, который вызывает эту ошибку.
Если вы хотите отображать тост в методе doInBackground, тогда вы должны написать свою логику Toast внутри потока пользовательского интерфейса.
см. ниже ссылку ответа
fooobar.com/info/216995/...
Но не рекомендуется иметь манипуляцию с пользовательским интерфейсом под потоком не-ui