android中webview的交互

webview中js调用Java代码

大概思路是写一个Java类,然后通过webview的addJavascriptInterface方法把那个类传到页面中,然后页面就能直接通过指定的名字调用方法

布局就是上面一个webview下面一个textView

mainactivity.Java

public class MainActivity extends Activity implements JsBridje{

    private WebView mWebView;
    private TextView mTextView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView = (WebView)findViewById(R.id.wv_webview);
        mTextView = (TextView)findViewById(R.id.tv_result);

        //允许webview加载js
        mWebView.getSettings().setJavaScriptEnabled(true);
        //2.创建一个js接口类,jsinterface
        //3.创建一个就是接口类传递到webview中,第一个参数是Java接口类对象,第二个是传入到js中的名称
        mWebView.addJavascriptInterface(new JsInterface(this),"javaslei");

        //加载要显示的html
        mWebView.loadUrl("file:///android_asset/index.html");
    }

    //重写一个jsbridje接口,让jsinterface类能够调用,改变UI
    @Override
    public void setvalue(String value) {
        mTextView.setText(value);
    }
}

可以看到调用的addjavascriptinterface方法第一个参数是传入了一个对象,第二个参数是一个字符串,在js中直接调用字符串.方法即可

JsInterface.java

public class JsInterface {
    private static final String TAG = "JsInterface";
    private JsBridje jsBridje;

    public JsInterface(JsBridje jsBridje) {
        this.jsBridje = jsBridje;
    }

    /**
     * 从js中调用的方法,这个方法不在主线程中执行,所以不能在这里改变UI
     * @param value
     */
    @JavascriptInterface
    public void setvalue(String value){
        jsBridje.setvalue(value);
    }
}

js调用的方法一定要加上@JavascriptInterface

因为要改变页面内容,所以引入了一个什么设计模式实现一jsbridje接口

JsBridje.java

public interface JsBridje {
    void setvalue(String value);
}

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webview</title>
    <script type="text/javascript">
        function oclick(){
            var inputEle = document.getElementById('uservalue');
            if(window.javaslei){
                javaslei.setvalue(inputEle.value);
            }else{
                alert('没找到Java对象');
            }
        }
    </script>
</head>
<body>
    <h2>webview</h2>
    <div>
        <span>请输入要传递的值</span>
        <input type="text" id="uservalue" />
        <p onclick="oclick()">提交</p>
    </div>
</body>
</html>

可以看到,在html中直接调用javaslei(mainactivity传入的名字).setvalue方法就能调用了jsinterface类中的方法,然后这个方法通过调用jsbridje的接口方法去调用mainactivity.java的setvalue方法改变textview的值


java中调用js代码

其实就一行:mWebView.loadUrl("javascript:要执行的命令");

布局文件是webview和一个edittext和一个button

mainactivity.java

public class MainActivity extends Activity{

    private WebView mWebView;
    private EditText meditview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView = (WebView)findViewById(R.id.wv_webview);
        meditview = (EditText) findViewById(R.id.tv_value);

        //允许webview加载js
        mWebView.getSettings().setJavaScriptEnabled(true);

        //加载要显示的html
        mWebView.loadUrl("file:///android_asset/index.html");
    }

    public void onclick(View view) {
        String value = meditview.getText().toString();
        mWebView.loadUrl("javascript:if(window.remote){window.remote('"+value+"')}");
    }
}

可以看到直接调用了js中的remote方法传入了一个字符串参数,注意那个字符串参数前后要加上单引号

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webview</title>
    <script type="text/javascript">
        function remote(str){
            document.write(str);
        }
    </script>
</head>
<body>
</body>
</html>

html中就一个remote方法,就是把获取到的值写到界面中


使用chrome调试APP中的网页

先启用调试mWebView.setWebContentsDebuggingEnabled(true);

然后chrome访问chrome://inspect/

然后就能看到相应的inspect,点进去就能调试,不过肯定打不开,因为需要翻墙.或者下载离线包

解决了上面的内容就能够像调试网页的方式一样去调试APP中的html代码


一些常见的错误

  1. 当js调用java 代码出现了throw,此时APP并不会崩溃,但是会在html的控制台中抛出一个错误

  2. 如果js没有判断是否有相应的方法就去调用会出现找不到方法的错误

  3. 参数类型错误,常见的有数组和对象里面的问题,因为js是弱类型语言,而Java是强类型,,所以如果类型有错误会导致程序出错

  4. 字符串为空值的时候会传入一个字符串类型的undefined,解决办法就是当要传入的对象为空值的时候,传一个""就行

xwm

还是一个菜鸟


Comments are closed.