在这篇文章中,我们将带领您了解ANDROID:在Webview和httpclient之间共享会话的全貌,包括android与webview交互的相关情况。同时,我们还将为您介绍有关androidHtt
在这篇文章中,我们将带领您了解ANDROID:在Webview和httpclient之间共享会话的全貌,包括android与webview交互的相关情况。同时,我们还将为您介绍有关android HttpClient+WebView 同步cookie、Android HttpClient,DefaultHttpClient,HttpPost、android listview的item中有webview,但是点击webview会没有反应?、android okhttp和webview session共享的知识,以帮助您更好地理解这个主题。
本文目录一览:- ANDROID:在Webview和httpclient之间共享会话(android与webview交互)
- android HttpClient+WebView 同步cookie
- Android HttpClient,DefaultHttpClient,HttpPost
- android listview的item中有webview,但是点击webview会没有反应?
- android okhttp和webview session共享
ANDROID:在Webview和httpclient之间共享会话(android与webview交互)
我实际上在WebView中记录了会话.
但我也使用httpclient来发送和从网络获取数据.我在互联网上看到,无法获取WebView的内容,因此我需要使用我的httpclient从Web服务获取数据.
问题是这个webservice使用会话…而我的会话在我的WebView中,所以httpclient没有它,我无法访问webservice的内容.
我看到很多关于这个问题的帖子,但我不明白解决方案.
这是我在onPageStarted上做的:
CookieManager mgr = CookieManager.getInstance();
Log.i( "URL", url );
Log.i("Cookie",mgr.getCookie("mywebsite.com"));
String cookie_string = mgr.getCookie("mywebsite.com");
if(cookie_string.length() > 1) {
Data.instance().getPref().edit().putString("cookie",cookie_string).commit();
}
我看到我有这样的东西,所以我希望那些也包括会话:
(我删除号码)
__utma=......(number)......;
__utmc=number;
__utmz=number.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);
wt3_eid=%number%number;
wt3_sid=%number
然后我不知道该怎么做才能在我的httpclient中设置这个cookie.我尝试了,没有成功:
HttpClient client = new DefaultHttpClient();
BasicCookieStore cookieStore = new BasicCookieStore();
String login_cookie_string = Data.instance().getPref().getString("cookie", "");
String[] cookie_parts = null;
if(login_cookie_string.length()> 0)
{
//debug_view.setText(login_cookie_string);
Log.d("COOKIE", login_cookie_string);
cookie_parts = login_cookie_string.split(";");
for(int t=0;t < cookie_parts.length;t++)
{
String[] cookieContent = cookie_parts[t].split("=");
Cookie login_cookie = new BasicclientCookie(cookieContent[0],cookieContent[1]);
((BasicclientCookie) login_cookie).setDomain("mywebsite.com");
cookieStore.addCookie(login_cookie);
}
}
((AbstractHttpClient) client).setCookieStore(cookieStore);
解决方法:
所以,这就是我所做的,它对我有用 –
HttpRequestBase request = new HttpGet(uri);
request.addHeader("Cookie", getCookieFromAppCookieManager(uri.toString()));
现在,getCookieFromAppCookieManager的实现如下 –
该方法从应用程序CookieManager获取给定URL的cookie.应用程序CookieManager管理应用程序的WebView实例使用的cookie.
@param url the URL for which the cookies are requested
@return value the cookies as a string, using the format of the 'Cookie' HTTP request header
@throws MalformedURLException
public static String getCookieFromAppCookieManager(String url) throws MalformedURLException {
CookieManager cookieManager = CookieManager.getInstance();
if (cookieManager == null)
return null;
String rawCookieHeader = null;
URL parsedURL = new URL(url);
// Extract Set-Cookie header value from Android app CookieManager for this URL
rawCookieHeader = cookieManager.getCookie(parsedURL.getHost());
if (rawCookieHeader == null)
return null;
return rawCookieHeader;
}
android HttpClient+WebView 同步cookie
android客户端通过httpClient或者httpUrlConnection进行登录后,为了把登录状态同步到webView中,这时需要进行cookie的同步
参考:http://segmentfault.com/a/1190000002877843
一.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();
//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主页面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不推荐,但完全可以使用
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);
}
}
Android HttpClient,DefaultHttpClient,HttpPost
public static String postData(String url,String postData)抛出SomeCustomException
字符串url的格式应该是什么
返回String是来自服务器的响应,作为json数据的字符串表示.
编辑
目前的连接工具
package my.package; import my.package.exceptions.CustomException; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URLDecoder; import org.apache.http.httpentity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; public class ConnectionUtil { public static String postData(String url,String postData) throws CustomException { // Create a new HttpClient and Post Header InputStream is = null; StringBuilder sb = null; String result = ""; HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(); httppost.setHeader("host",url); Log.v("ConnectionUtil","opening POST connection to URI = " + httppost.getURI() + " url = " + URLDecoder.decode(url)); try { httppost.setEntity(new StringEntity(postData)); // Execute HTTP Post Request HttpResponse response = httpclient.execute(httppost); httpentity entity = response.getEntity(); is = entity.getContent(); } catch (Exception e) { Log.e("log_tag","Error in http connection " + e.toString()); e.printstacktrace(); throw new CustomException("Could not establish network connection"); } try { BufferedReader reader = new BufferedReader(new InputStreamReader( is,"utf-8"),8); sb = new StringBuilder(); sb.append(reader.readLine() + "\n"); String line = "0"; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); result = sb.toString(); } catch (Exception e) { Log.e("log_tag","Error converting result " + e.toString()); throw new CustomException("Error parsing the response"); } Log.v("ConnectionUtil","Sent: "+postData); Log.v("ConnectionUtil","Got result "+result); return result; } }
Logcat输出
10-16 11:27:27.287: E/log_tag(4935): Error in http connection java.lang.NullPointerException
10-16 11:27:27.287: W/System.err(4935): java.lang.NullPointerException
10-16 11:27:27.287: W/System.err(4935): at org.apache.http.impl.client.AbstractHttpClient.determineTarget(AbstractHttpClient.java:496)
10-16 11:27:27.307: W/System.err(4935): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
10-16 11:27:27.327: W/System.err(4935): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
10-16 11:27:27.327: W/System.err(4935): at in.gharpay.zap.integration.ConnectionUtil.postData(ConnectionUtil.java:92)
10-16 11:27:27.327: W/System.err(4935): at in.gharpay.zap.integration.ZapTransaction$1.doInBackground(ZapTransaction.java:54)
10-16 11:27:27.327: W/System.err(4935): at in.gharpay.zap.integration.ZapTransaction$1.doInBackground(ZapTransaction.java:1)
10-16 11:27:27.327: W/System.err(4935): at android.os.AsyncTask$2.call(AsyncTask.java:185)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
10-16 11:27:27.327: W/System.err(4935): at java.lang.Thread.run(Thread.java:1019)
10-16 11:27:27.327: V/log_tag(4935): Could not establish network connection
解决方法
// Build the JSON object to pass parameters JSONObject jsonObj = new JSONObject(); jsonObj.put("username",username); jsonObj.put("data",dataValue); // Create the POST object and add the parameters HttpPost httpPost = new HttpPost(url); StringEntity entity = new StringEntity(jsonObj.toString(),HTTP.UTF_8); entity.setContentType("application/json"); httpPost.setEntity(entity); HttpClient client = new DefaultHttpClient(); HttpResponse response = client.execute(httpPost);
希望这有助于解决您的问题.谢谢.
android listview的item中有webview,但是点击webview会没有反应?
listview的item中嵌套有webview,给listview设置了onclickItem的点击事件,但是当点到webview的位置时没有响应,其他位置却可以,应该怎么设置才能在点到webview的位置时也有响应?android okhttp和webview session共享
public static OkHttpClient get(Context context){
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.cookieJar(new WebViewCookieHandler(context))
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.cache(new Cache(context.getCacheDir(), Config.REQUEST_CACHE_SIZE));
return builder.build();
}
public class WebViewCookieHandler implements CookieJar {
private CookieManager mCookieManager = CookieManager.getInstance();
public Context context;
public WebViewCookieHandler(Context context){
this.context = context;
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
mCookieManager.setAcceptCookie(true);
String urlString = url.toString();
for (Cookie cookie : cookies) {
mCookieManager.setCookie(urlString, cookie.toString());
}
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
CookieSyncManager.getInstance().sync();
}else{
mCookieManager.flush();
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
String urlString = url.toString();
String cookiesString = mCookieManager.getCookie(urlString);
if (cookiesString != null && !cookiesString.isEmpty()) {
String[] cookieHeaders = cookiesString.split(";");
List<Cookie> cookies = new ArrayList<>(cookieHeaders.length);
for (String header : cookieHeaders) {
cookies.add(Cookie.parse(url, header));
}
return cookies;
}
return Collections.emptyList();
}
今天关于ANDROID:在Webview和httpclient之间共享会话和android与webview交互的讲解已经结束,谢谢您的阅读,如果想了解更多关于android HttpClient+WebView 同步cookie、Android HttpClient,DefaultHttpClient,HttpPost、android listview的item中有webview,但是点击webview会没有反应?、android okhttp和webview session共享的相关知识,请在本站搜索。
本文标签: