0

Je suis en train de courir beaucoup AsyncTasks faire loadData() sur le même WebView. Par exemple, j'ai 3 threads avec 3 contenus: "One", "Two", "Three" et un WebView avec le contenu "abc". (Comme le code ci-dessous)AsyncTasks multiples chargent le même WebView

Après 3 tâches terminées, je veux le WebView a contenu: "abcOneTwoThree". L'idée de ce code est que trois threads vont ajouter son contenu à WebView à tout moment, donc le résultat pourrait être "abcTwoOneThree" ou "abcTwoThreeOne", etc ...

Je lis beaucoup d'articles de concurrence mais je ne comprends toujours pas comment mettre en œuvre cela. C'est mon code. Il imprime juste "abcThree".

public class UsingSameWebViewActivity extends Activity implements OnClickListener { 
    private Button button1; 
    private WebView webView; 
    private String result; 

    @Override 
    public void onCreate(final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     button1 = (Button)findViewById(R.id.button1); 
     button1.setOnClickListener(this); 
     webView = (WebView)findViewById(R.id.webView1); 
     result = "abc"; 
    } 

    @Override 
    public void onClick(final View v) { 
     final String[] contents = {"One", "Two", "Three"}; 
     for(int i = 0; i < 3; ++i) { 
      final FooTask task = new FooTask(webView, result); 
      task.execute(contents[i]); 
     } 
    } 

    private class FooTask extends AsyncTask<String, Void, String> { 
     private final WebView resultView; 
     private String result; 

     // This is what I try to make it work right. 
     private synchronized String getResult() { 
      return result; 
     } 

     public FooTask(final WebView resultView, final String result) { 
      this.resultView = resultView; 
      this.result = result; 
     } 

     @Override 
     protected String doInBackground(final String... params) { 
     // Do a long time work randomly then returns a string. 
      return params[0]; 
     } 

     @Override 
     protected void onPostExecute(final String content) { 
      result = getResult() + content; 
      resultView.loadData(result, "text/html", "utf-8"); 
     } 
    } 
} 

Répondre

1

Retirez la ligne private String result; de la classe Async tâche.

+0

Il fonctionne, mais si FooTask n'est pas classe interne. Je dois passer 'résultat' à FooTask comme dans mon code? – Emerald214

+0

Ensuite, faites de 'result' un membre' static' de la 'tâche asynchrone'. Votre problème consiste essentiellement à ajouter votre chaîne de caractères avec une chaîne vide, la rendre statique et cela devrait fonctionner. –

+0

... mais l'utilisation de l'électricité statique est assez bizarre. : | Je ne sais pas si c'est une bonne pratique. – Emerald214

1

Il n'y a rien à faire ici .. il suffit d'ajouter cette ligne task.execute(contents[i]); dans postExecute() de AsynTask et de rendre son contenu [i] comme une variable de classe .. task.execute(contents[i]); appellent cela deux fois depuis que vous voulez qu'il fasse « un "et « deux »

+0

Non, je veux chaque tâche à son contenu ajoute la variable résultat puis le charger sur WebView immédiatement. c'est-à-dire que la tâche A ajoute «un» au résultat, la tâche B ajoute «deux» au résultat, ... l'ordre n'est pas important. Si j'ai mal compris votre réponse, veuillez ajouter du code. – Emerald214

+0

Thats ce que je veux dire .. Vous pouvez appeler AsyncTask l'intérieur postExecute plusieurs fois .. et il sera probablement servir votre but .. – ngesh

1

Dans onPostExecute() vous voulez « revenir » quelque part le résultat. C'est-à-dire FooTask a besoin d'une place pour mettre son résultat. Un candidat probable serait une sorte de méthode FooTask peut appeler sur son appelant pour placer le résultat. Si vous faites cela, notez que la méthode doit être synchronized, sinon certains retours peuvent être perdus.

Alternativement vous pouvez donner FooTask un Handler qu'il peut envoyer un Message avec le résultat. Dans ce cas, vous n'aurez pas besoin de synchroniser quoi que ce soit puisque tous les Message seront envoyés au thread principal/interface utilisateur qui les traitera en série.

Questions connexes