刚做过的一个项目中用到了webview的一些功能,在开发过程中遇到了各种各样的问题,在此记录下来供大家参考:(下面代码是从项目中抽取出来的,供参考)
1.怎么给webview添加加载进度条?
2.怎么给webview设置cookie?
3.怎么在webview中让服务端可以直接调用APP端的方法?
(补充:因为之前我在做这个项目的时候,百度 谷歌了很多,都描述的不是很详细,所以我详细的给过一遍,希望能帮助到大家)
主要就是这三个问题的解决,下面我们一个一个的解释。
1.在webview中添加加载进度条。
这个其实很简单,我自己做了一个自定义进度条progress,然后使用webview自身的setWebChromeClient()方法去实时更新progress的值。代码如下
web.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int newProgress) { // TODO Auto-generated method stub super.onProgressChanged(view, newProgress); //newProgress就是当前的进度 progress.setProgress(newProgress); if (newProgress == 100) { progress.setVisibility(View.GONE); } else { progress.setVisibility(View.VISIBLE); } } });
这个是webview自己的一个加载进度的回调,我在这里加了一个加载完成后就自动隐藏进度条的方法。
2.给webview setCookie。
每个写服务器的人习惯以及命名规则不一样,不要去网上找来方法死板硬套,要灵活运用。直接给代码吧:
CookieSyncManager.createInstance(getApplicationContext()); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); List<Cookie> cookie = Utils.cookieStore.getCookies(); List<String> listcookie = new ArrayList<String>(); for (int i = 0; i < cookie.size(); i++) { Cookie cookie2 = cookie.get(i); listcookie.add(cookie2.getName() + "=" + cookie2.getValue() + ";domain=" + cookie2.getDomain() + ";path=" + cookie2.getPath()); cookieManager.setCookie(url, listcookie.get(i)); } CookieSyncManager.getInstance().sync(); // 强制立即同步cookie
这个是我项目中的原句,其中: listcookie.add(cookie2.getName() + "=" + cookie2.getValue() + ";domain=" + cookie2.getDomain() + ";path=" + cookie2.getPath()); 这句为什么这么写,与网上你能搜到的写法都不一样。之前在这里我花费了很大的功夫(主要是当时cookie不懂的原理),为了让大家少走弯路,我解释一下。上面提到过每一个后台开发人员他们的开发习惯不一样,
他们给你返回返回的cookie格式也有可能不一样。如果你不理解cookie的定义这里你就有可能去绕弯子了。首先Cookie是由服务器端生成,发送给User-Agent,然后下次我们需要请求服务器端的时候携带上去,让服务器端去分辨我们是不是合法的用户。cookie是以key/value保存的。成对存在,一般是数组格式。 上面的代码就是我根据我们的服务端需要自己拼接而成的cookie set 给了webview。另外有时会失效,不要怕,在onResume()中加入CookieSyncManager.getInstance().startSync();在onPause()中加入CookieSyncManager.getInstance().stopSync(); 一般写到这里,你的cookie已经设置成功了。3.在webview中让服务端可以直接调用APP端的方法这个问题与上面的cookie毫无关系,有的人认为要向服务端可以调用本地就必须先设置cookie,其实不是必须的。因为他们是没有关系的。首先我们需要声明一些方法,具体意义自己去百度就不详细说了,代码中有注释
// 注入js方法 WebSettings webSettings = web.getSettings(); webSettings.setSavePassword(false); webSettings.setSaveFormData(false); webSettings.setSupportZoom(false); web.setBackgroundColor(R.color.transparent); web.setWebViewClient(new myWebViewClient()); // 将一个java对象绑定到一个javascript对象中,javascript对象名就是interfaceName,作用域是Global. web.addJavascriptInterface(new JavaScriptInterface(DataWebActivity.this), "JavaScriptInterface"); web.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); web.getSettings().setBuiltInZoomControls(true); // 设置可以访问文件 web.getSettings().setAllowFileAccess(true); // 如果访问的页面中有Javascript,则webview必须设置支持Javascript web.getSettings().setJavaScriptEnabled(true); web.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); web.getSettings().setAppCacheEnabled(true); web.getSettings().setDomStorageEnabled(true); web.getSettings().setDatabaseEnabled(true);
JavaScriptInterface在自己的代码中必须实现这个接口,且名称一致。
class JavaScriptInterface { private Context mContext; public JavaScriptInterface(Context c) { mContext = c; } // 跳转到汗滴界面 @JavascriptInterface public void jumpClientGetScore() { finish(); } // 跳转到兑换记录页面 @JavascriptInterface public void jumpClientOrder() { new Handler().postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }, 1); finish(); } // 跳转到保存地址界面 @JavascriptInterface public void jumpClientAddress() { mHandler.postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }, 100); finish(); } // 分享 @JavascriptInterface public void jumpInvite(final String url, final String title, final String describe) { mHandler.postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }, 100); } }
如果你原文不懂的把我的复制过去,然后服务端照着这个接口去调用,那你的问题就已经解决了。但是在这里我重点说下:
1.必须传上下文,这个虽然都知道,但是我还是要重点提出来。
2.必须在方法前面加注解 @JavascriptInterface 原因自己百度,别人已经总结的很好了。但是我知道没加的都调用不成功。
3.为什么我在被调用的方法里面加入了延时操作?由于这个是我去年搞的项目,具体原因也忘了。好像是直接调用的话,有可能大网络延时从而导致调用方法成功了,但是方法里面的
东西却执行不成功,主要针对的是intent 其他页面。
好了,理科生,也不知道描述的清除不?大家将就着看吧,如有不明白的可以再问题。