Несколько AsyncTasks загружают один и тот же WebView - PullRequest
0 голосов
/ 01 августа 2011

Я пытаюсь запустить много 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 ]

1 голос
/ 01 августа 2011

Удалите строку private String result; из класса асинхронных задач.

1 голос
/ 02 августа 2011

В onPostExecute() вы хотите «вернуть» ваш результат куда-нибудь. Это означает, что FooTask нужно место, чтобы поставить свой результат. Вероятным кандидатом может быть какой-то метод FooTask, который может вызвать вызывающую программу для размещения результата. Если вы сделаете это, обратите внимание, что метод должен быть synchronized, в противном случае некоторые из возвратов могут быть потеряны.

В качестве альтернативы вы можете дать FooTask a Handler, что он может отправить Message с результатом. В этом случае вам не нужно ничего синхронизировать, поскольку все Message будут отправлены в основной поток / поток пользовательского интерфейса, который будет обрабатывать их последовательно.

1 голос
/ 01 августа 2011

Здесь особо нечего делать ... просто добавьте эту строку task.execute(contents[i]); в postExecute() из AsynTask и сделать содержимое [i] переменной класса .. task.execute(contents[i]); вызвать это дважды, так как вы хотите, чтобы он делал «один» и «два»

...