WebViewClient onPageFinished从来没有所谓的 [英] WebViewClient onPageFinished never called

查看:277
本文介绍了WebViewClient onPageFinished从来没有所谓的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了看S / O几个类似的职位,但我无法找到一个答案,我的问题。我想抓住从Web视图中的HTML,但我不能让我的onPageFinished()回调开火。我甚至一直在使用的WebChromeClient进度回调试过,但没有什么工作。嘶鸣Web客户端或网页镀铬的客户收到任何回调。我正在这个code作为一个Android的单元测试,并使用从资产目录中的HTML测试我已经通过断言和调试确认被定位。我缺少什么?

**的更新 **
我已经通过在调试试验方法加强。它加载HTML(这是一个单元测试,所以我不能真正看到呈现的内容)。它然后在等待()调用块,超时然后执行在底部的断言而没有从任一客户端接收一回呼。 (无论是Web客户端和客户端铬应该/将调用notify())

这里的区别是,我是一个Android的单元测试中运行。 web视图没有连接到任何活动或容器。我不知道是否有任何与丢失的回调。我会尽力坚持它的活动,看看它是否有什么差别。
** / 更新 **

 公共类MyWebViewTest扩展InstrumentationTestCase {    私人的WebView web视图;
    私人字符串HTML;    公共无效设置()抛出异常{
        super.setUp();
        上下文的背景下= getInstrumentation()的getContext()。
        this.webView =新的WebView(背景);
        assertTrue(要求的test.html
                。Arrays.asList(。context.getResources()getAssets()列表(WWW))包含(test.html的));
    }    公共无效拆解()抛出异常{    }    @JavascriptInterface
    公共无效viewContent(字符串内容){
        this.html =内容;
    }
    公共无效testCanLoadAndReadWebContentFromWebView()抛出异常{
        webView.addJavascriptInterface(这一点,_webContainer);
        webView.getSettings()setJavaScriptEnabled(真)。
        webView.setWebViewClient(新WebViewClient(){
            @覆盖
            公共无效onPageFinished(web视图网页视图,字符串URL){
                super.onPageFinished(web视图,URL);
                onPageLoaded(web视图);
            }            @覆盖
            公共无效onPageStarted(的WebView视图,字符串URL,位图图标){
                super.onPageStarted(查看,网址,图标);
            }
        });        webView.setWebChromeClient(新WebChromeClient(){
            @覆盖
            公共无效onProgressChanged(的WebView观点,诠释newProgress){
                super.onProgressChanged(查看,newProgress);
                如果(newProgress == 100)
                    onPageLoaded(web视图);
            }
        });        webView.loadUrl(文件:///android_asset/www/test.html);
        同步(本){
            等待(5000);
        }
        assertNotNull(HTML);
    }
    私人无效onPageLoaded(web视图的WebView){
        webView.loadUrl(JavaScript的:window._webContainer.viewContent(document.documentElement.innerHTML););
        同步(本){
            通知();
        }
    }
}


解决方案

我在我的假设是正确的!当Webview是没有附加到活动也不会载入,渲染,或做更多的事情。我结束了延长ActivityInstrumentationTestCase2和附加的网络视图的活动。在这一点上我在回调断点开始点亮。这里是我工作的测试用例:

 公共类MyWebViewTest扩展ActivityInstrumentationTestCase2< TestMeActivity> {    私人的WebView web视图;
    私人字符串HTML;    公共MyWebViewTest(){
        超(TestMeActivity.class);
    }    公共无效设置()抛出异常{
        super.setUp();
        上下文的背景下= getInstrumentation()的getContext()。
        this.webView = getActivity()getView()。
        assertTrue(要求的test.html
                。Arrays.asList(。context.getResources()getAssets()列表(WWW))包含(test.html的));
    }    公共无效拆解()抛出异常{    }    @JavascriptInterface
    公共无效viewContent(字符串内容){
        this.html =内容;
    }    公共无效testCanLoadAndReadWebContentFromWebView()抛出异常{
        getActivity()。runOnUiThread(新的Runnable(){
            @覆盖
            公共无效的run(){
                configureWebView();
            }
        });
        同步(MyWebViewTest.this){
            MyWebViewTest.this.wait(25000);
        }
        的assertEquals(< HEAD>< /头><身体GT; \\ n+
                你好\\ n+
                \\ n+
                < /身体gt;中,HTML);
    }    私人无效configureWebView(){
        webView.addJavascriptInterface(这一点,_webContainer);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(真);
        webView.setWebViewClient(新WebViewClient(){
            @覆盖
            公共无效onPageFinished(web视图网页视图,字符串URL){
                super.onPageFinished(web视图,URL);
                onPageLoaded(web视图);
            }
        });        webView.loadUrl(文件:///android_asset/www/test.html);
    }
    @TargetApi(Build.VERSION_ codeS.KITKAT)
    私人无效onPageLoaded(web视图的WebView){
        webView.evaluateJavascript(\"javascript:window._webContainer.viewContent(document.documentElement.innerHTML);\",
                新ValueCallback<串GT;(){
                    @覆盖
                    公共无效onReceiveValue(字符串值){
                        同步(MyWebViewTest.this){
                            MyWebViewTest.this.notify();
                        }
                    }
                }
        );
    }
}

和这里是我扔在一起来支持它的活动:

 公共类TestMeActivity延伸活动{    私人的WebView视图。    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        鉴于=新的WebView(本);
        的setContentView(视图);
    }    公众的WebView getView(){
        返回视图。
    }
}

在短期有相当多涉及从Android TestCase的测试的WebView内容的一些工作。你有一个Javascript接口添加到Web视图,插入一些JavaScript调用内部的JavaScript接口对象,通过Web视图的内容,通过该接口,并最终收在你的测试用例。我当然希望它是更容易,但,这是我能拿出最好的。

I've looked at several similar posts on S/O but I can't find an answer to my problem. I'm trying to grab the html from a web view but I can't get my "onPageFinished() callback to fire. I've even tried using the progress callback on the WebChromeClient but nothing is working. neigh the web client or web chrome client receive any callbacks. I am running this code as an Android unit test and using a test HTML from the assets directory which I've confirmed via assert and debug is being located. What am I missing?

** Update ** I've stepped through the test method in debug. It does load the html (it's a unit test so I cannot actually see the rendered content). It then blocks on the wait() call, times out then performs the assert at the bottom without ever receiving a callback from either client. (Both the web client and chrome client should/would call notify())

The difference here would be that I am running within an Android unit test. The WebView is NOT attached to any Activity or container. I'm wondering if that has anything to do with the missing callbacks. I'll try sticking it on an Activity to see if it makes any difference. ** /Update **

public class MyWebViewTest extends InstrumentationTestCase {

    private WebView webView;
    private String html;

    public void setUp() throws Exception {
        super.setUp();
        Context context = getInstrumentation().getContext();
        this.webView = new WebView(context);
        assertTrue("requires test.html",
                Arrays.asList(context.getResources().getAssets().list("www")).contains("test.html"));
    }

    public void tearDown() throws Exception {

    }

    @JavascriptInterface
    public void viewContent(String content) {
        this.html = content;
    }
    public void testCanLoadAndReadWebContentFromWebView() throws Exception {
        webView.addJavascriptInterface(this, "_webContainer");
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView webView, String url) {
                super.onPageFinished(webView, url);
                onPageLoaded(webView);
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }
        });

        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                if(newProgress==100)
                    onPageLoaded(webView);
            }
        });

        webView.loadUrl("file:///android_asset/www/test.html");
        synchronized (this) {
            wait(5000);
        }
        assertNotNull(html);
    }


    private void onPageLoaded(WebView webView) {
        webView.loadUrl("javascript:window._webContainer.viewContent(document.documentElement.innerHTML);");
        synchronized (this) {
            notify();
        }
    }
}

解决方案

I was correct in my assumption! When the WebView is not attached to an Activity it will not load, render, or do much of anything. I ended up extending ActivityInstrumentationTestCase2 and attaching the web view to an Activity. At that point my breakpoints in the callbacks started lighting up. Here's my working test case:

public class MyWebViewTest extends ActivityInstrumentationTestCase2<TestMeActivity> {

    private WebView webView;
    private String html;

    public MyWebViewTest() {
        super(TestMeActivity.class);
    }

    public void setUp() throws Exception {
        super.setUp();
        Context context = getInstrumentation().getContext();
        this.webView = getActivity().getView();
        assertTrue("requires test.html",
                Arrays.asList(context.getResources().getAssets().list("www")).contains("test.html"));
    }

    public void tearDown() throws Exception {

    }

    @JavascriptInterface
    public void viewContent(String content) {
        this.html = content;
    }

    public void testCanLoadAndReadWebContentFromWebView() throws Exception {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                configureWebView();
            }
        });
        synchronized (MyWebViewTest.this) {
            MyWebViewTest.this.wait(25000);
        }
        assertEquals("<head></head><body>\n" +
                "Hello\n" +
                "\n" +
                "</body>",html);
    }

    private void configureWebView() {
        webView.addJavascriptInterface(this, "_webContainer");
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView webView, String url) {
                super.onPageFinished(webView, url);
                onPageLoaded(webView);
            }
        });

        webView.loadUrl("file:///android_asset/www/test.html");
    }


    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void onPageLoaded(WebView webView) {
        webView.evaluateJavascript("javascript:window._webContainer.viewContent(document.documentElement.innerHTML);",
                new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        synchronized (MyWebViewTest.this) {
                            MyWebViewTest.this.notify();
                        }
                    }
                }
        );
    }
}

and here's the Activity I threw together to back it:

public class TestMeActivity extends Activity{

    private WebView view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new WebView(this);
        setContentView(view);
    }

    public WebView getView() {
        return view;
    }
}

In short there is quite a bit of work involved in testing the contents of a WebView from an Android TestCase. You have to add a Javascript interface to the web view, insert some Javascript to invoke the internal Javascript interface object, passing the contents of the web view, through the interface and finally collect it in your test case. I sure wish it were easier but this is the best I can come up with.

这篇关于WebViewClient onPageFinished从来没有所谓的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆