使用JSOUP将文档加载到WebView [英] Load document to WebView with JSOUP

查看:183
本文介绍了使用JSOUP将文档加载到WebView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将网页的一部分解析为WebView。我正在使用jsoup库来获取我需要的页面的一部分,然后加载到webview。
这是代码:

I'm trying to parse a part of webpage to WebView. I'm using jsoup library to get part of page that i need, and then load to webview. Here is code:

public void loadArticleWithHTML (){
    Thread downloadThread = new Thread() {
        public void run() {
            try {
                doc = Jsoup.connect("http://en.wikipedia.org/").get();
                element = doc.select("#mp-itn b a");

            } catch (java.io.IOException e){
                e.printStackTrace();
            }
        }
    };
    downloadThread.start();

    mWebView.setWebViewClient(new WebViewClient() {
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Toast.makeText(getApplicationContext(), description, Toast.LENGTH_SHORT).show();
        }
    });
    try {
        mWebView.loadData(element.html(), "text/html", "UTF-8");
    } catch (NullPointerException e){
        e.printStackTrace();
        Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_LONG).show();
    }

}

但我总是收到错误


尝试在空对象引用上调用虚方法'java.lang.String org.jsoup.select.Elements.html()' / p>

Attempt to invoke virtual method 'java.lang.String org.jsoup.select.Elements.html()' on a null object reference


推荐答案

您的问题是您正在使用线程下载和解析HTML内容(即正确的事情)然后你试图从元素外部线程加载。因为下载页面需要一些时间才能完成,所以在初始化之前调用 element.html()因此为null - 这就是为什么你得到NullPointerException。

Your problem is that you are using a thread to download and parse the HTML content (that's the correct thing to do) and then you are trying to load from the Element object outside the thread. Because downloading the page takes some time to finish, you are calling element.html() before it has been initialize and is therefore null - which is why you are getting a NullPointerException.

为了解释发生了什么,让我们看一下 loadArticleWithHtml 方法的流程:

To explain what's going on, lets look at the flow of your loadArticleWithHtml method:


  1. 您创建一个应该下载并解析HTML的线程

  2. 您可能启动线程并下载页面开始

  3. 您设置WebViewClient

  4. 您将数据加载到WebView并尝试访问 element.html()(元素尚未初始化并且仍然为空)并获得空指针异常

  5. 之后,页面下载完成并且元素已初始化

  1. You create a thread that is supposed to download and parse HTML
  2. You start the thread and the downloading of the page probably starts
  3. You set the WebViewClient
  4. You load data into the WebView and try to access element.html() (element has not been initialized yet and is still null) and get a Null Pointer Exception
  5. Sometime after, the page downloading finishes and element is initialized

我建议您阅读更多关于threadin摹。当您使用线程时,该进程与UI线程(您正在加载HTML的位置)并行运行,并且不保证在UI线程中的其余代码完成之前完成。事实上,在UI线程上工作并在其中间启动一个线程,几乎可以保证线程将在UI代码完成后完成,如果代码执行任何缓慢的下载等操作。

I suggest you read more about threading. When you use a thread, the process runs in parallel to the UI thread (which is where you are loading the HTML) and is not guaranteed to finish before the rest of your code in the UI thread does. In fact, doing work on the UI thread and starting a thread in the middle of it, it is almost guaranteed that the thread will finish after the UI code finishes if the code is doing anything slow like downloading.

因此,解决方案是正确地线程化您的应用程序并加载WebView AFTER 元素变量已从线程内初始化。见下文。

So, the solution is to correctly thread your application and load the WebView AFTER the element variable has been initialized from within the thread. See below.

public void loadArticleWithHTML (){
    Thread downloadThread = new Thread() {
        public void run() {
            try {
                doc = Jsoup.connect("http://en.wikipedia.org/").get();
                element = doc.select("#mp-itn b a");

            } catch (java.io.IOException e){
                e.printStackTrace();
            }
            if (element == null) {
                Log.e("error", "There is a problem with the selection");
            } else {
                // post a new Runnable from a Handler in order to run the WebView loading code from the UI thread
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        mWebView.loadData(element.html(), "text/html", "UTF-8");
                    }
                });
            }
        }
    };

    mWebView.setWebViewClient(new WebViewClient() {
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Toast.makeText(getApplicationContext(), description, Toast.LENGTH_SHORT).show();
        }
    });

    downloadThread.start();
}

注意,你需要从UI线程运行WebView方法,因为它是一个视图,应该从主线程访问。有关运行代码的其他信息,请参阅此Q / A UI线程。

Note, you need to run the WebView method from the UI thread as it is a view and should be accessed from the main thread. See this Q/A for additional info on running code on the UI thread.

这篇关于使用JSOUP将文档加载到WebView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆