android客户端经过httpClient或者httpUrlConnection进行登陆后,为了把登陆状态同步到webView中,这时须要进行cookie的同步
javascript
参考:http://segmentfault.com/a/1190000002877843 php
一.cookie同步方式java
下面是登陆线程:android
public class LoginThread extends Thread{ private Handler loginHandler; public LoginThread(Handler loginHandler) { this.loginHandler = loginHandler; } @Override public void run() { List<String> cookieLst = new ArrayList<String>(); HttpParams httpParams = new BasicHttpParams(); ConnManagerParams.setMaxTotalConnections(httpParams, 5); ConnManagerParams.setTimeout(httpParams, 15*1000); HttpConnectionParams.setSoTimeout(httpParams, 10*1000); HttpConnectionParams.setTcpNoDelay(httpParams, true); HttpPost httpPost = new HttpPost("http://192.168.1.107/cookie/login.php"); List<NameValuePair> nvPairs = new ArrayList<NameValuePair>(); nvPairs.add(new BasicNameValuePair("name", "lisi")); nvPairs.add(new BasicNameValuePair("age","22")); nvPairs.add(new BasicNameValuePair("gender", "男")); try { UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvPairs, HTTP.UTF_8); httpPost.setEntity(entity); HttpClient httpClient = new DefaultHttpClient(); //Cookie可能获取不到,所以有必要调用浏览器兼容模式 HttpClientParams.setCookiePolicy(httpClient.getParams(), CookiePolicy.BROWSER_COMPATIBILITY); HttpResponse httpResponse = httpClient.execute(httpPost); if(httpResponse!=null && httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK) { String content = EntityUtils.toString(httpResponse.getEntity()); Log.d("LOGIN", content); Header[] allHeaders = httpResponse.getAllHeaders(); if(allHeaders!=null) { //获取cookie的第一种方式 for (Header header : allHeaders) { Log.d("LOGIN", header.getName()+"="+header.getValue()); if("Set-Cookie".equalsIgnoreCase(header.getName())) { cookieLst.add(header.getValue()); } } } //获取cookie的第二种方式 AbstractHttpClient abstractHttpClient = (AbstractHttpClient) httpClient; CookieStore cookieStore = abstractHttpClient.getCookieStore(); List<Cookie> cookies = cookieStore.getCookies(); for (Cookie cookie : cookies) { Log.d("LOGIN-COOKIE", cookie.getName()+"="+cookie.getValue()+",path="+cookie.getPath()+",domain="+cookie.getDomain()+",expires="+cookie.getExpiryDate()); } if(loginHandler!=null) { Message msg = new Message(); msg.obj = cookieLst; msg.what = 200; msg.setTarget(loginHandler); msg.sendToTarget(); } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
下面是WebView主页面Activityweb
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public class Main extends Activity implements DownloadListener { private WebView mWebView; //extraHeaders经测试不能够同步cookie private Map<String, String> extraHeaders; private final String TAG = "WEB_VIEW"; private final Handler loginHandler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==200) { List<String> cookies = (List<String>) msg.obj; if(cookies!=null) { syncCookieToWebView(cookies); mWebView.loadUrl("http://192.168.1.107/cookie/read.php"); } }else{ super.handleMessage(msg); } } }; @SuppressLint("SetJavaScriptEnabled") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.main_webview); WebSettings settings = mWebView.getSettings(); settings.setAppCacheEnabled(true); settings.setCacheMode(WebSettings.LOAD_DEFAULT); settings.setGeolocationEnabled(true); settings.setUseWideViewPort(true); settings.setSaveFormData(true); settings.setSavePassword(true); settings.setSupportZoom(false); settings.setLoadsImagesAutomatically(true); settings.setBlockNetworkImage(false); if(android.os.Build.VERSION.SDK_INT>=11) { settings.setEnableSmoothTransition(true); } settings.setJavaScriptCanOpenWindowsAutomatically(false); settings.setAllowFileAccess(false); settings.setJavaScriptEnabled(true); String userAgent = settings.getUserAgentString(); Log.d(TAG, userAgent); if(android.os.Build.VERSION.SDK_INT>=14) { mWebView.setFitsSystemWindows(true); } if(mWebView.isHardwareAccelerated()) { mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null); } mWebView.setKeepScreenOn(true); extraHeaders = new IdentityHashMap<String, String>(); mWebView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(view!=null && !TextUtils.isEmpty(url)) { extraHeaders.put("control-cache", "no-cache,private"); extraHeaders.put("pragma", "no-cache,no-store"); extraHeaders.put("expires", "0"); view.loadUrl(url, extraHeaders); return true; } return super.shouldOverrideUrlLoading(view, url); } }); mWebView.setDownloadListener(this); //mWebView.loadUrl("http://shouji.baidu.com/software/?from=web_alad_multi"); new LoginThread(loginHandler).start(); } //销毁webView @Override protected void onDestroy() { super.onDestroy(); mWebView.clearFormData(); mWebView.clearHistory(); mWebView.destroy(); } //监听文件下载,WebView不会自动下载,须要咱们本身构建下载代码 @Override public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype, long contentLength) { Log.d(TAG, "url="+url); Log.d(TAG, "userAgent="+url); Log.d(TAG, "contentDisposition="+contentDisposition); Log.d(TAG, "mimetype="+mimetype); Log.d(TAG, "contentLength="+contentLength); //第一种下载方式是 自定义的http工具类 //new DownloadThread(url,contentDisposition,mimetype,contentLength).start(); //第二种下载方式是调用系统的webView,具备默认的进度条 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); } /** * cookie同步 */ private void syncCookieToWebView(List<String> cookies) { CookieSyncManager.createInstance(Main.this); CookieManager cm = CookieManager.getInstance(); cm.setAcceptCookie(true); if(cookies!=null) { for (String cookie : cookies) { cm.setCookie("http://192.168.1.107:80",cookie);//注意端口号和域名,这种方式能够同步全部cookie,包括sessionid } } CookieSyncManager.getInstance().sync(); } }
二.注意:平时开发中Cookie同步是最佳选项,但这并不意味着必定须要使用cookie同步,咱们可使用 token+用户id+登陆时间校验码 进行同步登陆segmentfault
三.对于使用javaInterface进行同步登陆的问题浏览器
javaInterface风险性很高,若是android平台是 4.2+比较安全,但4.2如下版本,安全性不容乐观,好比经过反射形成硬盘被读写的可能性很高!安全
在android 4.2中增长了 @javainterface注解,而且将公开的方法异步化,这样有效的控制了某些不必公开的方法被无心间做为接口公开,致使js发射到硬盘的读写io类,从而发生文件被窃取,垃圾文件堆积,有害文件被下载等问题!cookie
四.目前来讲让全部人使用 4.2+以上版本可能性不大,但尽可能少使用javainterface,转而使用 协议的方式,所谓协议,就是通讯协议,咱们能够分析url参数,从而进行webView和native代码的通讯session
mWebView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //捕获url的参数值 if(url.indexOf("login")>=0) { //客户端代码执行某部分操做----->执行完毕后经过url参数把执行结果返回webView }else if(url.indexOf("userCenter")>=0){ //客户端代码执行某部分操做----->执行完毕后经过url参数把执行结果返回webView } return super.shouldOverrideUrlLoading(view, url); } });
固然,javainterface不推荐,但彻底可使用
view.loadUrl("javascript:dosometing("+"'参数'"+")");
-------------------------------2015-04-30-更新,从webView读取cookie--------------------------------
private class MyWebViewClient extends WebViewClient { public boolean shouldOverrideUrlLoading(WebView view, String url) { webview.loadUrl(url); return true; } public void onPageFinished(WebView view, String url) { CookieManager cookieManager = CookieManager.getInstance(); String CookieStr = cookieManager.getCookie(url); Log.e("sunzn", "Cookies = " + CookieStr); super.onPageFinished(view, url); } }