02
2016
08

安卓webview中调试js脚本

安卓项目中,用webview加载html,与js进行交互,实现起来没有问题,但是调试起来很麻烦。

开发的时候用pc测试是比较方便的,谷歌火狐浏览器也支持模拟移动设备测试,但是真机测试,而且是直接用的webview加载html来测试,不同的设备,不同版本的安卓系统,都可能导致问题,调试起来很困难。

要是安卓中能捕获到js运行的错误信息(就是发生错误时,pc端浏览器的控制台输出的那些信息),调试起来就方便多了。

首先,查到了这个页面:http://www.tuicool.com/articles/n6b6B3,“重写WebViewClient类中的onReceivedError()方法和onReceivedSslError()方法来进行 处理”,试了试,发现不能满足要求,这个可以用来处理页面加载时出现的错误,比如“页面不存在”、“页面证书错误”等等。

无意间搜到了这个页面:http://www.2cto.com/kf/201404/292474.html

mWebview.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
        // TODO Auto-generated method stub
	if (consoleMessage.message().contains("Uncaught ReferenceError")) {
			// do something...
	}
	return super.onConsoleMessage(consoleMessage);
    }
});

复制上边这段代码,添加自己的输出代码,居然真的可以了。

onConsoleMessage是处理控制台输出信息的,可能一开始的思路错了,一直想着怎么实现webview捕获js的错误,其实js运行错误会从控制台输出,直接处理控制台输出信息就可以了。


java代码:

package com.example.webviewtest;

import android.os.Bundle;
import android.app.Activity;
import android.app.Instrumentation;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.webkit.ConsoleMessage;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class MainActivity extends Activity {

	private WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        webView=(WebView)findViewById(R.id.webView);
      //启用支持javascript
        WebSettings webSettings = webView.getSettings();
        webSettings.setSavePassword(false);
        webSettings.setSaveFormData(false);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setSupportZoom(false);
        
        webView.loadUrl("file:///android_asset/index.html");
        webView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
        
        webView.setWebViewClient(new MonitorWebClient()); 
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                // TODO Auto-generated method stub
            	Log.e("hanyeah", "consoleMessage:"+consoleMessage.message());
        	if (consoleMessage.message().contains("Uncaught ReferenceError")) {
        			// do something...
        	}
        	return super.onConsoleMessage(consoleMessage);
            }
        });
    }
    private class MonitorWebClient extends WebViewClient{  
    	  
        @Override  
        public void onReceivedError(WebView view, int errorCode,  
                String description, String failingUrl) {  
            //错误提示  
            Toast toast = Toast.makeText(getBaseContext(), "Oh no! " + description,  
                    Toast.LENGTH_LONG);  
            toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0);  
            toast.show();  
            Log.e("hanyeah", errorCode+"\n"+description+"\n"+failingUrl);
            //错误<strong>处理</strong>  
            try {  
            	webView.stopLoading();  
            } catch (Exception e) {  
            }  
            try {  
            	webView.clearView();  
            } catch (Exception e) {  
            }  
            if (webView.canGoBack()) {  
            	webView.goBack();  
            }  
        //  super.onReceivedError(view, errorCode, description, failingUrl);  
        }  
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    final class DemoJavaScriptInterface {

        DemoJavaScriptInterface() {
        }
        public void myToast(String s){
        	Toast.makeText(getApplicationContext(), s,Toast.LENGTH_SHORT).show();
        }
        public void sendKeyEvent(final int keyCode,final int type) {		
    		new Thread(new Runnable() {
                
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        
                        Instrumentation inst=new Instrumentation();
                        KeyEvent event ;
                        if(type==1){
                       	 event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
                       	 
                       }
                       else{
                   		event = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
                       }
                        inst.sendKeySync(event);
                    } catch (Exception e) {
                        // TODO: handle exception
                    	
                    }
                }
            }).start();
            
        }
        //end functions

    }//end class DemoJavaScriptInterface

    
}

js代码:

<html>
	<head>
		<title>webview</title>
		<script>
		window.onload=function(){
		console.log("loaded");
		var div=document.getElementById("div");
		div.innerHTML="111:"+new Data();//故意将Date拼错。
		}
		</script>
	</head>
	<body style="background:rgb(200,200,200)">
		hello webview.
		<div id="div"></div>
	</body>
</html>




« 上一篇下一篇 »

相关文章:

js的parseInt方法  (2019-2-15 9:12:44)

webgl开发调试工具  (2017-12-24 7:31:13)

闪电效果  (2017-11-28 15:4:19)

js中判断一个对象的类型  (2017-3-30 14:27:35)

安卓原生控件做时钟  (2017-3-3 16:48:11)

安卓利用反射调用@Hide隐藏函数  (2017-3-3 10:2:2)

安卓FileDescriptor  (2017-2-21 11:28:53)

安卓zxing实现二维码扫描  (2017-2-20 13:42:56)

解九连环  (2016-12-1 20:58:11)

DataURL与File,Blob,canvas对象之间的互相转换的Javascript  (2016-11-25 14:58:41)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。