2011-07-20 3 views
0

Je continue à obtenir une erreur dans mon doInBackground()Erreur dans doBackground AsyncTask?

07-20 21:05:20.859: ERROR/AndroidRuntime(3289): java.lang.RuntimeException: An error occured while executing doInBackground() 


07-20 21:05:20.859: ERROR/AndroidRuntime(3289): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

Voici ma méthode de AsyncTask.

   private class MyTask extends AsyncTask<Void, Void, Void>{ 


       @Override 
       protected Void doInBackground(Void... arg0) {try { 
          getImages(); 
          Log.v("MyTask", "Image 1 retreived"); 
          getImage2(); 
          Log.v("MyTask", "Image 2 retreived"); 
          getImage3(); 
          Log.v("MyTask", "Image 3 retreived"); 
          getImage4(); 
          Log.v("MyTask", "Image 4 retreived"); 
         } catch (IOException e) { 
          Log.e("MainMenu retreive image", "Image Retreival failed"); 
          e.printStackTrace(); 
         } 
        return null; 
       } 

       protected Void onPostExecute(){ 
        ((Gallery) findViewById(R.id.gallery)) 
          .setAdapter(new ImageAdapter(MainMenu.this)); 
        return null; 

       } 

         } 

} 

Et il tient toujours mon interface utilisateur pour une raison quelconque. l'interface utilisateur n'apparaît qu'après son fait.

Voici mon onCreate() où j'exécute la tâche asynchrone.

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 


MyTask myTask = new MyTask(); 

    myTask.execute(); 

} 
+0

Vous devez lire les différentes méthodes d'un 'AsyncTask'. De la façon dont vous l'avez écrit, vous récupérez vos images sur le thread de l'interface utilisateur et essayez de définir votre adaptateur dans un thread séparé (ce qui explique pourquoi vous obtenez l'erreur). –

+0

Votre 'onPostExecute()' ne sera pas appelé, car il ne fait pas partie de l'interface de 'AsyncTask', car il ne surcharge pas la bonne méthode. Les génériques que vous avez spécifiés suggèrent que votre méthode onPostExecute prendra un objet Void en tant que paramètre pour remplir le contrat 'AsyncTask'. La déclaration de méthode devrait ressembler à ceci: 'onPostExecute (Void notUsed)'. C'est la raison pour laquelle l'annotation '@ Override' est extrêmement utile. –

+0

donc @Override protected void onPostExecute (Void notUsed) {return; { – yoshi24

Répondre

0

Yoshi vous voulez réellement déplacer tout dans votre AsynkTask. Placez les fonctions load images dans la méthode do in background, puis sur l'appel setListAdapter dans la méthode onPostExecute, la méthode Doinbackground ne peut pas modifier ou mettre à jour une vue, mais l'onPostexecute devrait pouvoir le faire.

protected void onPostExecute(Exception error) { 
     try { 
      if (error == null) { 
       ((Gallery) findViewById(R.id.gallery)) 
         .setAdapter(new ImageAdapter(MainMenu.this)); 

      } else 

      throw error; 
     } catch (Throwable t) { 

     } 
    } 
+0

Je ne pense pas que vous vouliez entourer cela dans un 'try-catch'. La ligne 'throw error;' sera juste attrapée dans le 'catch (Throwable t)' –

+0

@jared regarde ma méthode AsyncTask mise à jour. onPostExecute n'est jamais appelé. seul le faire en arrière-plan – yoshi24

1

Vous ne pouvez pas manipuler l'interface utilisateur lorsque vous n'êtes pas dans le thread d'interface utilisateur.

AsyncTask documentation

Je vais sortir sur un membre et devinez que votre temps appel est getImages(). Si tel est le cas, ces appels de méthode doivent se produire dans la méthode doInBackground() et le code que vous avez actuellement dans la méthode doInBackground() doit probablement être déplacé vers la méthode onPostExecute().