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:
- You create a thread that is supposed to download and parse HTML
- You start the thread and the downloading of the page probably starts
- You set the WebViewClient
- 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
- 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.