Android - Webview HTML 代码提取不起作用 (Javascript)

Android - Webview HTML code extraction doesn't work (Javascript)

我正在编写一个应用程序: - 在 Webview 中加载 URL; - 通过 javascript 代码提取 HTML; - 在日志中显示提取的 HTML 代码。

因为我需要在不启用 Java 脚本的情况下加载页面(以避免页面的某些行为),我尝试了下面的代码: - 我在禁用 Java 脚本的情况下在 webview 中加载页面; - 加载页面后,我启用 Java 脚本; - 然后,应用程序执行提取 HTML 代码所需的 Java 脚本。

不幸的是,当代码在 Android 4.0.4 上以调试模式执行时,出现错误:

01-22 22:37:56.575: E/Web Console(7605): Uncaught TypeError: Cannot call method 'processHTML' of undefined at null:1

如果我删除 myBrowserSettings.setJavaScriptEnabled(false); 声明,在 loadurl 调用之后,一切正常。

我该怎么做才能让下面的代码正常工作?

package com.stefano.formfiller;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebSettings.PluginState;

public class MainActivity extends Activity {

    WebView myBrowser;
    String urlToBrowse = "http://www.mywebsite.com";
    String htmlCode = null;
    StringBuffer buffer = new StringBuffer();

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          myBrowser = (WebView)findViewById(R.id.webView1);

          //Browser settings
          WebSettings myBrowserSettings = myBrowser.getSettings();

          //Prevent cache to be used
          myBrowserSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
          myBrowserSettings.setAppCacheEnabled(false);

          //General settings
          myBrowserSettings.setJavaScriptEnabled(true);
          Log.d("Stefano", "JS enabled");

          //FIREFOX user agent
          myBrowserSettings.setUserAgentString("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");


          myBrowser.setWebChromeClient(new WebChromeClient());
          myBrowser.setWebViewClient(new WebViewClient() {
              public void onPageFinished(WebView view, String url) 
              { 

                    WebSettings myBrowserSettings = myBrowser.getSettings();
                    myBrowserSettings.setJavaScriptEnabled(true);
                    Log.d("Stefano", "JS enabled");

                    Log.d("Stefano", "OnPageFinished running"); 

              } });


          //Start the delayed HTML code extraction
          delayedStartHtmlExtractor(16000);
          Log.d("Stefano", "DelayedStart HTML Extractor launched");

          //Prepare Javascript to extract the HTML code from the webview
          myBrowser.addJavascriptInterface(new LoadListener(), "HTMLOUT");

          myBrowser.loadUrl(urlToBrowse);
          Log.d("Stefano", "Main URL requested");

          myBrowserSettings.setJavaScriptEnabled(false);
          Log.d("Stefano", "JS disabled");
    }   


    //Delayed HTML extraction
    public void delayedStartHtmlExtractor(final int delay){
        Handler handler = new Handler();

        handler.postDelayed(new Runnable() 
        {

            @Override
            public void run() 
            {                           


                myBrowser.loadUrl("javascript:window.HTMLOUT.processHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
                Log.d("Stefano", "HTML extraction launched");

                        }
            }, delay);
    }

    //Insert the HTML code in the log information

    class LoadListener{
        public void processHTML(String html)
        {
            Log.d("Stefano", "HTML Extraction in progress...");


            Log.e("HTML CODE",html);
        }
    }

更新: 我有一个疑问:代码在 Java 脚本启用时实例化 Java 脚本接口(通过 myBrowser.addJavascriptInterface(new LoadListener(), "HTMLOUT"););然后,我在 URL 调用后禁用 javascript,以便在页面完全加载时重新启用 Java 脚本。

可能是当我用实例化接口禁用 Java 脚本时,我 "cut-off the communication channel" 在 Javascipt 和 Java 代码之间?

当您实例化 LoadListener 对象时,请尝试以下操作:

this.new LoadListener();

首先,您应该将正确的注释 @JavascriptInterface附加到将通过Javascript interface调用的方法;在你的情况下:

    //..
    @JavascriptInterface
    public void processHTML(String html) {
        Log.d("Stefano", "HTML Extraction in progress...");
        Log.e("HTML CODE",html);
    }
    //..

"请注意,在加载页面之前,注入的对象不会出现在 JavaScript 中"

我想用 setJavaScriptEnabled(false) 加载页面根本不会注入任何 Javascript 对象,这就是您遇到此问题的方式。

可能的解决方法(未经测试)可能是这样的:

  • 始终使用 setJavaScriptEnabled(true)
  • 加载页面
  • 加载通过http://www.google.com/gwt/n的网页(将加载无JS或Flash的页面)
  • 做你的处理

在界面设置后添加myBrowser.loadData(...),像这样

myBrowser.addJavascriptInterface(new LoadListener(), "HTMLOUT");
myBrowser.loadData("", "text/html", null);
myBrowser.loadUrl(urlToBrowse);

此外,由于您将在 oncreate 方法结束时禁用 js,因此无需在首次亮相时启用它:)

希望对您有所帮助