android客户端通过httpClient或者httpUrlConnection进行登录后,为了把登录状态同步到webView中,这时需要进行cookie的同步
一.cookie同步方式
下面是登录线程:
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();
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主页面Activity
@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+登录时间校验码 进行同步登录
三.对于使用javaInterface进行同步登录的问题
javaInterface风险性很高,如果android平台是 4.2+比较安全,但4.2以下版本,安全性不容乐观,比如通过反射造成硬盘被读写的可能性很高!
在android 4.2中增加了 @javainterface注解,并且将公开的方法异步化,这样有效的控制了某些没必要公开的方法被无意间作为接口公开,导致js发射到硬盘的读写io类,从而发生文件被窃取,垃圾文件堆积,有害文件被下载等问题!
四.目前来说让所有人使用 4.2+以上版本可能性不大,但尽量少使用javainterface,转而使用 协议的方式,所谓协议,就是通信协议,我们可以分析url参数,从而进行webView和native代码的通信
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不推荐,但完全可以使用
?
1
view.loadUrl("javascript:dosometing("+"'参数'"+")");
分享到:
相关推荐
所以往往需要将在native方法...这种情况在Android开发中比较常见,因为Android不会自动同步cookie到WebView。做iOS开发则不用担心这个问题,因为iOS内部已经实现了cookie同步.本文就是一个小的事例,从登录到同步cookie
Android使用WebView加载登录的html界面,则通过登录成功获取Cookie并同步,可以是下一次不用登录也可以查看到个人信息,注:如果初始化加载登录,可通过缓存Cookie信息来验证是否要加载登录界面。Cookie信息包含了你...
Android WebView 去除标题 利用javacript交互
原生登录cookie保持提供webview使用
Android Webview虽然提供了页面加载及资源请求的钩子,但是对于h5的ajax请求并没有提供干涉的接口,这意味着我们不能在webview中干涉javascript发起的http请求,而有时候我们确实需要能够截获ajax请求并实现一些功能...
使用android studio 3.1.2 ,利用webview,实现登录界面。采用本地html 页面
Android Webview 滑动监听 放大缩小查看网页图片
Android webview 内存泄露的解决方法 最近在activity嵌套webview显示大量图文发现APP内存一直在涨,没法释放内存,查了很多资料,大概是webview的一个BUG,引用了activity导致内存泄漏,所以就尝试传递...
httpClient请求和服务器session保持同步,webView对cookie的管理
。。。。。。。Android webview QQ一键登录并向后台返回参数
Android WebView实现自由复制文字
android webview input=file 失效解决方案
Android webview 加载网页以及本地资源以及SD资源demo,以及加载缓存资源
主要介绍了解决Android webview设置cookie和cookie丢失的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
Android下使用Webview实现的HTML5视频播放器,播放本地视频时请加载video目录下的1.html
Android-X5WebView基本封装和使用 通过OkHttp拦截器、自定义CookieJar有效完成客户端与H5端的Cookie同步管理 监听WebView的加载进度 滚动条的设置(隐藏或者显示,内侧显示还是外侧显示) 优化X5WebView的预加载问题...
android webview模拟网页post操作
Android WebView播放视频开发中总结的一些经验,希望同大家分享,这个是相应的Demo,一些经验和注释都在代码中写到。
android WebView上传文件