0

Je suis en train de faire multithreading mais j'ai ce stacktrace sur quelques smartphones (SGS2):multitreading UI: exceptionininitializererror et exception d'exécution Android

java.lang.ExceptionInInitializerError 
at com.android.bordeaux.code.model.AnnouncersContainer.setLoudArrayFromJSON_online(AnnouncersContainer.java:68) 
at com.android.bordeaux.code.SplashscreenActivity_Second$1.run(SplashscreenActivity_Second.java:55) 
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
at android.os.Handler.<init>(Handler.java:121) 
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421) 
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421) 
at android.os.AsyncTask.<clinit>(AsyncTask.java:152) 
... 2 more 

Voici mon activité principale (splashscreen) Wich fait attendre pendant quelques secondes pour attendre ma finition AsyncTask:

public class SplashscreenActivity_Second extends Activity 
     {  
      @Override 
      public void onCreate(Bundle savedInstanceState) 
      { 
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.splashscreen_second); 

       // thread 
       Thread splashThread = new Thread() 
       { 
        @Override 
        public void run() 
        { 
         try 
         { 
          int waited = 0; 

          if (isInternetOn()) 
          { 
// Here I'm making my asynctask !! 
AnnouncersContainer.setLoudArrayFromJSON_online(getApplicationContext()); 
           while (waited < 5000) 
           { 
            sleep(50); 
            waited += 40; 
           } 
          } 
          else 
          {      
           AnnouncersContainer.setLoudArrayFromXML_local(getApplicationContext()); 
           while(waited < 5000) 
           { 
            sleep(50); 
            waited += 60; 
           } 
          } 
         } 
         catch(InterruptedException e) 
         { 
          e.printStackTrace(); 
         } 
         finally 
         { 
          Intent intent_to_tabhost = new Intent(SplashscreenActivity_Second.this, MyTabActivity.class); 
          startActivity(intent_to_tabhost); 
          finish(); 
         } 
        } 
       }; 
       splashThread.start(); 
      } 
} 

Voici mon AsyncTask:

public class DownloadAnnouncers extends AsyncTask<Void, Integer, Boolean> 
{ 
    public static Boolean loadFinished = false; 

    //JSON variables.. 


    private static String url = null; 

    Context context; 

    public DownloadAnnouncers(Context context) 
    { 
     this.context = context; 
    } 

    @Override 
    protected void onPreExecute() 
    { 
     super.onPreExecute(); 
    } 

    protected Boolean doInBackground(Void... params) 
    { 

    // fine retrieving all my JSON data in a global array.. 

    } 

    @Override 
    protected void onPostExecute(Boolean downloadedArray) 
    { 
     super.onPostExecute(downloadedArray); 
    } 
} 

Je sais que le problème est que je fais multithreading dans l'interface utilisateur, mais quelqu'un peut me dire comment supprimer mon fil de mise en boucle et en le remplaçant juste avec méthode onPostExecute() de mon AsyncTask ?? (Il pourrait être préférable d'attendre AsyncTask se termine plutôt que de faire attendre ..)

Ou peut-être me aider à corriger ce bug avec multithreading ..

EDIT:

mon AsyncTask:

public class DownloadAnnouncers extends AsyncTask<Void, Integer, Boolean> 
    { 
     public static Boolean loadFinished = false; 

     //JSON variables.. 


     private static String url = null; 

     Context context; 

     public DownloadAnnouncers(Context context) 
     { 
      this.context = context; 
     } 

     @Override 
     protected void onPreExecute() 
     { 
      super.onPreExecute(); 
     } 

     protected Boolean doInBackground(Void... params) 
     { 

     // fine retrieving all my JSON data in a global array.. 

     } 

     @Override 
     protected void onPostExecute(Boolean downloadedArray) 
     { 
      super.onPostExecute(downloadedArray); 
     Intent intent_to_tabhost = new Intent(context, MyTabActivity.class); 
     intent_to_tabhost.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(intent_to_tabhost); 
     } 
    } 

Mais maintenant, si j'appuie sur le bouton annuler Je retourne à mon activité splashscreen .. et je ne peux pas faire ctx.finish() dans la méthode onPostExecute ..

Répondre

1

Yo u ne peut pas créer un Handler dans un thread qui n'a pas appelé Looper.prepare(), comme message d'erreur dit:

Impossible de créer gestionnaire intérieur thread qui n'a pas appelé Looper.prepare()

le gestionnaire est créé au sein du AsyncTask, donc ce n'est pas quelque chose que vous pourriez voir dans un premier temps.

Si vous voulez garder votre code tel qu'il est vous fixer en déplaçant la création du AsyncTask à l'extérieur de votre fil personnalisé.

Cependant, vous n'avez pas besoin de créer le thread, vous pouvez simplement créer votre AsyncTask dans le thread ui (il fonctionnera sur son propre thread afin de ne pas verrouiller votre téléphone pendant le travail), et effectuer tout l'action que vous voulez après que la tâche soit terminée dans le onPostExecute -method.

class ExampleAsync extends AsyncTask<Void, Integer, Boolean> 
{ 
    public static Boolean loadFinished = false; 
    //JSON variables.. 
    private static String url = null; 
    Context context; 

    public DownloadAnnouncers(Context context){ 
     this.context = context; 
    } 

    protected Boolean doInBackground(Void... params){ 
     // fine retrieving all my JSON data in a global array.. 
    } 

    @Override 
    protected void onPostExecute(Boolean downloadedArray){ 
     Intent intent_to_tabhost = new Intent(context, MyTabActivity.class); 
     startActivity(intent_to_tabhost); 
    } 
} 

Et dans votre activité:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.splashscreen_second); 
    AsyncTask myTask = new ExampleAsync(this); 
    myTask.execute(); 
} 
0

Au lieu d'attendre le AsyncTask, utilisez le onPostExecute, qui est appelé sur le thread d'interface utilisateur seulement une fois la tâche terminée.

Vous devez également annuler la tâche si l'activité a été détruite (par exemple si l'utilisateur a appuyé sur le bouton de retour alors que l'écran de démarrage est affiché).

+0

Enfin cela fonctionne, j'ai dû ajouter l'asynctask dans mon activité splashscreen (l'asynctask n'était pas interne avant) donc je peux appeler finish() – eento

Questions connexes