J'essaie d'afficher Toast dans ma classe initial_background étendue avec AsyncTask<URL, Integer, Long>
. Je reçois cette erreur dans 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();
}
}
}
C'est l'exception:
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
Le code ci-dessus montre toute l'histoire. En fait, je veux montrer un toast dans la méthode doInBackground
Vous ne pouvez pas mettre à jour l'interface utilisateur sur le fil d'arrière-plan. doInBackground()
est invoqué sur le thread d'arrière-plan. Vous devez mettre à jour l'interface utilisateur sur le fil de l'interface utilisateur.
runOnUiThread(new Runnable(){
@Override
public void run(){
//update ui here
// display toast here
}
});
onPreExecute()
, onPostExecute(Result)
, sont appelés sur le thread d'interface utilisateur. Vous pouvez donc afficher le pain grillé ici.
onProgressUpdate(Progress...)
, appelé sur le thread d'interface utilisateur après un appel à publishProgress(Progress...)
peut être utilisé pour animer une barre de progression ou afficher les journaux dans un champ de texte.
Le résultat du calcul de doInBackground()
est un paramètre de onPostExecute(Result)
alors renvoyez le résultat en doinBackground()
et affichez votre pain grillé en onPostExecute(Result)
Vous pouvez également utiliser un gestionnaire comme suggéré par @Stine Pike
Pour plus de clarté, consultez le lien ci-dessous sous le sujet: Les 4 étapes.
http://developer.Android.com/reference/Android/os/AsyncTask.html
Créez un objet de gestionnaire et exécutez tous vos messages Toast à l'aide de cet objet.
@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();
}
});
}
C'est une autre manière qui n'est pas mentionnée ici comme suit:
Étape 1: Définir Gestionnaire en tant que global
Handler handler;
Étape 2: Initialise le gestionnaire dans doInBackground () méthode comme suit:
@Override
protected Void doInBackground(Void... params) {
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
//your code
}
}
};
}
Étape 3: Et maintenant, vous pouvez appeler ce gestionnaire n'importe où dans le code en appelant
if(handler != null){
handler.sendEmptyMessage(1);
}
Ce que vous pouvez faire de plus, c'est que vous pouvez envoyer des données via le gestionnaire comme suit:
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putInt("KEY", value);
message.setData(bundle);
handler.sendMessage(message);
Et gérer les données dans votre gestionnaire comme ci-dessous
handler = new Handler(){
@Override
public void handleMessage(Message message) {
Bundle bundle = message.getData();
Integer value = bundle.getInt("KEY");
}
};
affichez votre pain grillé dans onPostExecute ou onPreExecute. doInBackGround s'exécute sur un thread séparé, mais les deux autres méthodes s'exécutent sur le thread d'interface utilisateur.
Mais s'il est indispensable de montrer le pain grillé dans doInBackGround, vous pouvez utiliser Handler.post ou runonUiThread pour afficher le pain grillé.
Vous ne pouvez pas afficher Toast dans un fil non-UI (c'est-à-dire faire en arrière-plan) .Vous pouvez essayer le concept du drapeau.
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();
}
}
Happy Coding .. !!! entrez le code ici
nous pouvons le faire en passant une interface à la classe AsyncTask et en effectuant un rappel dans onPostExecute method.
public interface IResult {
void onSuccess(String result);
void onError(String error);
}
public static class AsyncTaskClass extends AsyncTask<String, String, Boolean> {
IResult iResult;
AsyncTaskClass(IResult iResult){
this.iResult = iResult;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... params) {
boolean result;
try {
//doing BackGround Operation Here
result = true;
} catch (Exception e) {
Log.e(TAG,"Error: " + e.getMessage());
result = false;
}
return result;
}
@Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
Log.w(TAG, "On Post Execute: " + success);
if(success)
iResult.onSuccess("AsyncTask done successfully.");
else
iResult.onSuccess("Sorry! something went wrong.");
}
}
IResult iResult = new IResult() {
@Override
public void onSuccess(String result) {
Toast.makeText(PostActivity.this, result, Toast.LENGTH_LONG).show();
}
@Override
public void onError(String error) {
Toast.makeText(PostActivity.this, error, Toast.LENGTH_LONG).show();
}
};
String param1 = "some value 1";
String param2 = "some value 2";
new AsyncTaskClass(iResult).execute(param1, param2);`
Vous essayez d'afficher du pain grillé dans un fil non-ui, c'est pourquoi cette erreur apparaît.
Si vous souhaitez afficher toast dans la méthode doInBackground, vous devez écrire votre logique Toast dans le fil de l'interface utilisateur.
jetez un oeil à ci-dessous le lien de réponse https://stackoverflow.com/a/11797945/582571
Mais il n'est pas conseillé d'avoir une manipulation de l'interface utilisateur sous un thread non-ui