Несколько AsyncTasks загружают один и тот же WebView
Я пытаюсь запустить много AsyncTasks для выполнения loadData() в одном и том же WebView. Например, у меня есть 3 потока с 3 содержимым: "Один", "Два", "Три" и WebView с содержимым "abc". (как код ниже)
После того, как 3 задачи завершены, я хочу, чтобы WebView содержал: "abcOneTwoThree". Идея этого кода заключается в том, что три потока будут добавлять его содержимое в WebView в любое время, поэтому результатом может быть "abcTwoOneThree" или "abcTwoThreeOne" и т. Д.
Я прочитал много статей по параллелизму, но все еще не понимаю, как это реализовать. Это мой код Он просто печатает "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");
}
}
}
3 ответа
Здесь особо нечего делать... просто добавьте эту строку task.execute(contents[i]);
в postExecute()
из AsynTask
и сделать содержимое [i] как переменную класса.. task.execute(contents[i]);
вызовите это дважды, так как вы хотите, чтобы он сделал "один" и "два"
В onPostExecute()
Вы хотите "вернуть" свой результат куда-нибудь. Это сказать FooTask
нужно место, чтобы поставить свой результат. Вероятным кандидатом будет какой-то метод FooTask
может вызвать вызывающего абонента для размещения результата. Если вы делаете это примечание, что метод должен быть synchronized
в противном случае некоторые из возвратов могут быть потеряны.
По-другому вы могли бы дать FooTask
Handler
что он может отправить Message
чтобы с результатом. В этом случае вам не нужно ничего синхронизировать, так как все Message
s будут отправлены в основной поток / пользовательский интерфейс, который будет обрабатывать их последовательно.