多个AsyncTask加载同一个WebView

发布于 2024-11-27 10:04:41 字数 1947 浏览 1 评论 0原文

我正在尝试运行许多 AsyncTasks 在同一个 WebView 上执行 loadData() 。例如,我有 3 个线程,包含 3 个内容:“一”、“二”、“三”和一个包含内容“abc”的 WebView。 (如下面的代码)

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");
        }
    }
}

I'm trying to run many AsyncTasks to do loadData() on the same WebView. For example, I have 3 threads with 3 contents: "One", "Two", "Three" and a WebView with content "abc". (like the code below)

After 3 tasks finished, I want the WebView has content: "abcOneTwoThree". The idea of this code is that three threads will append its content to WebView at anytime, so the result could be "abcTwoOneThree" or "abcTwoThreeOne", etc ...

I read many concurrency articles but still don't understand how to implement this. This is my code. It just prints "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");
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深空失忆 2024-12-04 10:04:41

从 Async Task 类中删除 private String result; 行。

Remove the private String result; line from the Async Task class.

夕色琉璃 2024-12-04 10:04:41

这里没什么可做的..只需添加此行 task.execute(contents[i]);
AsynTaskpostExecute()中并将contents[i]作为类变量..task.execute(contents[i]);调用这两次,因为你希望它执行“一”和“二”

There is nothing much to do here.. just add this line task.execute(contents[i]);
in postExecute() of AsynTask and make contents[i] as a class variable.. task.execute(contents[i]); call this twice since you want it to do "one" and "two"

↘紸啶 2024-12-04 10:04:41

onPostExecute() 中,您希望将结果“返回”到某个地方。这就是说 FooTask 需要一个地方来放置其结果。一个可能的候选者是某种方法 FooTask 可以调用其调用者来放置结果。如果执行此操作,请注意该方法必须同步,否则某些返回结果可能会丢失。

或者,您可以为 FooTask 提供一个 Handler,它可以向其发送包含结果的 Message。在这种情况下,您不需要同步任何内容,因为所有 Message 都将发送到主/UI 线程,主线程将串行处理它们。

In onPostExecute() you want to "return" your result somewhere. This is to say FooTask needs a place to put its result. A likely candidate would be some sort of method FooTask can call on its caller to place the result. If you do this note that the method must be synchronized, otherwise some of the returns may be lost.

Alternately you could give FooTask a Handler that it can send a Message to with the result. In this case, you will not need to synchronize anything since all the Messages will be sent to the main/UI thread which will process them serially.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文