Load document to WebView with JSOUP

前端 未结 2 454
孤街浪徒
孤街浪徒 2021-01-14 13:32

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          


        
相关标签:
2条回答
  • 2021-01-14 14:09

    I think you are not aware of the fact that

    doc.select("#mp-itn b a")
    

    will return with Elements, i.e. a collection of matching Element nodes, despite your usage of # in the CSS selector, which should indeed only return one Element. If you use

    doc.select("#mp-itn b a").first()
    

    it at least gets the Element with the id you want. Maybe there is more issues to your code though, I did not check for that.

    Addendum

    i am not very familiar with Android development, but the error you are getting points towards a null pointer issue, indicating that element is null where you try to invoke element.html()

    0 讨论(0)
  • 2021-01-14 14:24

    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.

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

    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

    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.

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

    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.

    0 讨论(0)
提交回复
热议问题