【问题标题】:Saving data from a WebView从 WebView 保存数据
【发布时间】:2016-05-05 08:02:57
【问题描述】:

我需要保存在 WebView 上显示的数据。 我通过保存在 WebViewClient 中发出的所有 URL 请求并将它们发送到后端服务来实现这一点。后端服务稍后会请求这些文件。

问题是 WebViewClient 正在运行它自己的周期并且响应不可见,这导致我为每个资源发出两个请求。

有什么方法可以直接在 WebViewClient 中获取数据?

这是一段正在运行的当前代码:

private class Client extends WebViewClient{
@Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        plainText = //get plain text and save it
        webView.loadDataWithBaseURL(url, plainText, MIME_TYPE_TEXT_HTML, UTF_8_ENCODING, null);
        return true;
    }
    @SuppressWarnings("deprecation")
    @Override
    public synchronized WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        // we need to make sure it does nothing in this one for >= lollipop as in lollipop the call goes through both methods
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return interceptRequest(view, url, null);
        }
        return null;
    }
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        WebResourceResponse response = super.shouldInterceptRequest(view, request);
        final String url = request.getUrl().toString();
        return interceptRequest(view, url, response);
    }

    private WebResourceResponse interceptRequest(WebView webView, String url, WebResourceResponse webResourceResponse) {
        addUrlToDownloadQueue(url);
        return webResourceResponse;
    }

addUrlToDownloadQueue(url); 负责将所有 url 传递给检索所有源的服务。

有什么方法可以在不将数据传递给后端服务的情况下获取 WebViewClient 上的数据?

【问题讨论】:

  • 我还没有完全理解你想要达到的目标。您想从 WebView 读取/获取数据还是要将数据插入 WebView?
  • @LorenzoCamaione,两者都有。第一次访问网页想读取/获取数据,下次访问特定网页想将数据插入WebView
  • @Yazan,我不是在处理 javascript.. 处理好了..
  • @Vishal,我的后端服务保存所有 .js .css .hml ..etc 文件及其名称。当用户离线时,所有这些文件都保存在手机上。而不是显示用户离线页面,我可以向他们显示保存的页面。我不必使用任何 java 脚本。而不是 webView.loadUrl(url) 我调用 webView.loadDataWithBaseURL(url, data, mimeType, encoding, mHistoryUrl)

标签: android webview


【解决方案1】:

你看过之前的question?

如果您无法实现目标,请告诉我。

【讨论】:

  • html资源不由我决定...它可以随时更改。我必须能够保存任何页面上显示的所有内容
  • 不可能使用可变页面,因为您使用 html id 与页面交互。但是,您可以从后端获取这些 ID,这样您就可以更改您在应用中使用的 ID,而无需更新您的应用。
【解决方案2】:

我正在发布另一个答案,因为这个答案太长,不适合在评论中。

好吧,如果您不控制网页,那么回答这个问题并不好。事实上,正如 android 开发者指南中所说:“注意:使用 addJavascriptInterface() 允许 JavaScript 控制你的 Android 应用程序。这可能是一个非常有用的功能,也可能是一个危险的安全问题。当 WebView 中的 HTML 不可信时(例如,部分或所有 HTML 由未知人员或进程提供),则攻击者可以包含执行您的客户端代码的 HTML,以及可能是攻击者选择的任何代码。”

要在网页中获取数据,您可以使用 webView.loadUrl("javascript: document.getElementById("example").value;");

要从网页获取数据,请尝试参考此page.

如果您需要更多帮助,请联系我!!

【讨论】:

  • onPageFinished 不保证每次都被调用...网页可能会失败。这也不会保存所有外部调用的内容。
  • 有可能!!!!事实上,在 Web 视图中执行任何操作之前,您应该进行一些检查。你能做到吗?
【解决方案3】:

你可以试试这个,可能对你有帮助。

public class TestActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.webview);
    final WebView webview = (WebView) findViewById(R.id.browser);
    webview.getSettings().setJavaScriptEnabled(true);
    webview.addJavascriptInterface(new MyJavaScriptInterface(this), "HtmlViewer");

    webview.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            webview.loadUrl("javascript:window.HtmlViewer.showHTML" +
                    "('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
        }
    });

    webview.loadUrl("http://android-in-action.com/index.php?post/" +
            "Common-errors-and-bugs-and-how-to-solve-avoid-them");
}

class MyJavaScriptInterface {

    private Context ctx;

    MyJavaScriptInterface(Context ctx) {
        this.ctx = ctx;
    }

    public void showHTML(String html) {
        new AlertDialog.Builder(ctx).setTitle("HTML").setMessage(html)
                .setPositiveButton(android.R.string.ok, null).setCancelable(false).create().show();
    }

}
}

【讨论】:

    【解决方案4】:

    在提交之前查看我的示例以获取数据:
    https://github.com/henrychuangtw/WebView-Javascript-Inject

    并停止向后端传递数据,在 onsubmit 函数中返回 false

    webview1.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
    
            StringBuilder sb = new StringBuilder();
            sb.append("document.getElementsByTagName('form')[0].onsubmit = function () {");
            sb.append("var objPWD, objAccount;var str = '';");
            sb.append("var inputs = document.getElementsByTagName('input');");
            sb.append("for (var i = 0; i < inputs.length; i++) {");
            sb.append("if (inputs[i].type.toLowerCase() === 'password') {objPWD = inputs[i];}");
            sb.append("else if (inputs[i].name.toLowerCase() === 'email') {objAccount = inputs[i];}");
            sb.append("}");
            sb.append("if (objAccount != null) {str += objAccount.value;}");
            sb.append("if (objPWD != null) { str += ' , ' + objPWD.value;}");
            sb.append("window.MYOBJECT.processHTML(str);");
            sb.append("return true;"); //return false, to stop onsubmit function
            sb.append("};");
    
            view.loadUrl("javascript:" + sb.toString());
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2015-01-06
      • 1970-01-01
      • 2012-10-14
      • 2011-06-17
      相关资源
      最近更新 更多