Reputation: 45
So the app shows up the dialog while loading but then crashes. Te reason I decided t use these technologies is because I have to load an html, which changes dynamically and there are heavy CSS files which I would like to cache, so I think including them as assets is a good idea. I use Jsoup because I am able to get the html page without having to download the full content. Here's the code:
public class MyWebViewFragment extends Fragment {
ProgressDialog mProgress;
WebView webview;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.web_fragment, container,
false);
Bundle bundle = getArguments();
String url = bundle.getString("url");
webview = (WebView) rootView.findViewById(R.id.webview1);
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
mProgress = ProgressDialog.show(getActivity(), "Loading",
"Please wait for a moment...");
fetchUrl thread = (fetchUrl) new fetchUrl().execute();
Document doc = thread.getDoc();
String htmlData = null;
doc.head().getElementsByTag("link").remove();
doc.head().appendElement("link").attr("rel", "stylesheet").attr("type", "text/css").attr("href", "style.css");
htmlData = doc.outerHtml();
//TODO fetchURL here
webview.loadDataWithBaseURL("file:///assets/", htmlData, "text/html", "UTF-8", null);
// webview.loadUrl(url);
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//TODO add assets loading he instead of urlLoad
//view.loadUrl(url);
return false;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (mProgress.isShowing()) {
mProgress.dismiss();
}
}
});
return rootView;
}
The class extending AsybcTask:
private class fetchUrl extends AsyncTask<Void, Void, Document>{
Document doc;
@Override
protected Document doInBackground(Void... param) {
try {
doc = Jsoup.connect("http://example.ch").userAgent("Chrome").get();//use url when ready
} catch (IOException ex) {
}
return doc;
}
}
And the error log:
--------- beginning of crash
E/AndroidRuntime( 5125): FATAL EXCEPTION: main
E/AndroidRuntime( 5125): Process: com.flexenergy.swapp, PID: 5125
E/AndroidRuntime( 5125): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.flexenergy.swapp/com.flexenergy.swapp.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'org.jsoup.nodes.Element org.jsoup.nodes.Document.head()' on a null object reference
E/AndroidRuntime( 5125): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
E/AndroidRuntime( 5125): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
E/AndroidRuntime( 5125): at android.app.ActivityThread.access$800(ActivityThread.java:151)
E/AndroidRuntime( 5125): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
E/AndroidRuntime( 5125): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 5125): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime( 5125): at android.app.ActivityThread.main(ActivityThread.java:5257)
E/AndroidRuntime( 5125): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5125): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime( 5125): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
E/AndroidRuntime( 5125): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
E/AndroidRuntime( 5125): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'org.jsoup.nodes.Element org.jsoup.nodes.Document.head()' on a null object reference
E/AndroidRuntime( 5125): at com.flexenergy.swapp.MyWebViewFragment.onCreateView(MyWebViewFragment.java:49)
E/AndroidRuntime( 5125): at android.app.Fragment.performCreateView(Fragment.java:2053)
E/AndroidRuntime( 5125): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
E/AndroidRuntime( 5125): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
E/AndroidRuntime( 5125): at android.app.BackStackRecord.run(BackStackRecord.java:834)
E/AndroidRuntime( 5125): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
E/AndroidRuntime( 5125): at android.app.Activity.performStart(Activity.java:6005)
E/AndroidRuntime( 5125): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
E/AndroidRuntime( 5125): ... 10 more
W/ActivityManager( 1219): Force finishing activity 1 com.flexenergy.swapp/.MainActivity
I/Choreographer( 1219): Skipped 30 frames! The application may be doing too much work on its main thread.
E/EGL_emulation( 919): tid 919: eglCreateSyncKHR(1237): error 0x3004 (EGL_BAD_ATTRIBUTE)
Upvotes: 0
Views: 625
Reputation: 707
AsyncTask is a concurrent process of your main thread so to use the result of that computation you need to wait until it completes his work.
You're trying to call doc.head()
but doc is a null reference because the asyncTask has not completed, then has not initialized doc
.
Do your stuff with doc
in the OnPostExecute(result)
method of the AsyncTask, in this way you'll be sure that doc
is correctly initialized.
Upvotes: 1