private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg)
{
CookieSyncManager.createInstance(MainActivity.this);
CookieManager cookieMgr = CookieManager.getInstance();
cookieMgr.setAcceptCookie(true);
cookieMgr.setCookie("", msg.obj.toString());// this place should add the login host address(not the login index address)
CookieSyncManager.getInstance().sync();
webview.loadUrl("");// login index address
};
};
这个时候发现webview加载的login index页面中可以自动的登陆了并显示登陆后的界面。
五、 WebView与JavaScript的交互
1. webview调用js
mWebView.loadUrl("javascript:do()");
以上是webview在调用js中的一个叫做do的方法,该js所在的html文件大致如下:
<html>
<script language="javascript">
/* This function is invoked by the webview*/
function do() {
alert("1");
}
</script>
<body>
<a><div >
<img src="https://www.linuxidc.com/Linux/2015-06/xx.png"/><br>
Click me!
</div></a>
</body>
</html>
2. js调用webview
我们假设下列的本地类是要给js调用的:
package com.test.webview;
class DemoJavaScriptInterface {
DemoJavaScriptInterface() {
}
/**
* This is not called on the UI thread. Post a runnable to invoke
* loadUrl on the UI thread.
*/
public void clickOnAndroid() {
mHandler.post(new Runnable() {
public void run() {
//TODO
}
});
}
}
首先给webview设置:
mWebview.setJavaScriptEnabled(true);
随后将本地的类(被js调用的)映射出去:
mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
“demo”这个名字就是公布出去给JS调用的,那么js久可以直接用下列代码调用本地的DemoJavaScriptInterface类中的方法了:
<body>
...
</body>
六、WebView与JavaScript相互调用混淆问题
若webview中的js调用了本地的方法,正常情况下发布的debug包js调用的时候是没有问题的,但是通常发布商业版本的apk都是要经过混淆的步骤,这个时候会发现之前调用正常的js却无法正常调用本地方法了。
这是因为混淆的时候已经把本地的代码的引用给打乱了,导致js中的代码找不到本地的方法的地址。
解决这个问题很简单,即在proguard.cfg文件中加上一些代码,声明本地中被js调用的代码不被混淆。下面举例说明:
第五节中被js调用的那个类DemoJavaScriptInterface的包名为com.test.webview,那么就要在proguard.cfg文件中加入:
-keep public class com.test.webview.DemoJavaScriptInterface{
public <methods>;
}
若是内部类,则大致写成如下形式:
-keep public class com.test.webview.DemoJavaScriptInterface$InnerClass{
public <methods>;
}
若android版本比较新,可能还需要添加上下列代码:
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*