使用AsyncTask获取jsoup的url时,Android应用程序崩溃

时间:2015-06-17 14:20:56

标签: android android-asynctask jsoup assets

因此,应用程序会在加载时显示对话框,但随后会崩溃。我之所以决定使用这些技术是因为我必须加载一个动态变化的html,并且我想要缓存很多CSS文件,所以我认为将它们作为资产包含在内是一个好主意。我使用Jsoup是因为我能够获取html页面而无需下载完整内容。 这是代码:

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

扩展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;   
    }


}

错误日志:

--------- 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)

1 个答案:

答案 0 :(得分:1)

AsyncTask是主线程的并发进程,因此要使用该计算的结果,您需要等到它完成工作。

您尝试调用doc.head()但是doc是空引用,因为asyncTask尚未完成,因此尚未初始化doc

在AsyncTask的doc方法中使用OnPostExecute(result)执行您的操作,这样您就可以确保doc已正确初始化。