为了完成学期实训,需要对新浪新闻网站进行读取,所以学习并封装了okhttp简单get和post的工具类。
本文参考了以下两篇文章:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html
http://blog.youkuaiyun.com/lmj623565791/article/details/47911083
如果需要详细的okhttp使用,建议看泡网的教程,需要完善的工具库,请看我鸿洋大神的文章。
鸿洋大神的封装太过完善- -很多东西app并用不到。。。
本着不能拿来主义,以及实用定制为主的精神,决定自行学习okhttp的使用。
关于项目中使用时发现的问题:
1.okhttp官方建议只使用一个client,但是对于访问不同网站时cookie混乱,需要自行设置header来区分不同会话。
2.有些网站的登录验证并不会返回网页,直接在cookie中生成id区分是否登录成功,并且会造成302重定位死循环。
解决办法当然是禁止自动跳转,百度各种无解然后翻api发现了这个:mOkHttpClient.setFollowRedirects(followRedirects);
以上就是具体问题和解决,下面放出工具类:
package com.toxicant.hua.okhttpdemo;
import android.os.Handler;
import android.os.Looper;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import java.io.IOException;
/**
* okhttp的get和post异步的封装
* Created by hua on 2015/12/15.
*/
public class OkhttpUitls {
private OkHttpClient mOkHttpClient=new OkHttpClient();
private static OkhttpUitls mInstance=null;
private String cookie="";//跨站点操作时需要对自行对不同cookie进行保存,访问时设置cookie以延续会话
//获取UI线程
private Handler mHandler= new Handler(Looper.getMainLooper());
//回调接口
interface MOkCallBack{
void onSuccess(String str);
void onError();
}
//获取实例
public static OkhttpUitls getInstance() {
if (mInstance == null)
{
synchronized (OkhttpUitls.class)
{
if (mInstance == null)
{
mInstance = new OkhttpUitls();
}
}
}
return mInstance;
}
/**
* get方式进行网络访问
* @param url 地址
* @param mCallBack 回调
*/
public void get(String url, final MOkCallBack mCallBack){
final Request request = new Request.Builder()
.url(url)
.header("cookie", cookie)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
mHandler.post(new Runnable() {
@Override
public void run() {
mCallBack.onError();
}
});
}
@Override
public void onResponse(final Response response) throws IOException {
cookie=response.header("set-cookie");
final String re=response.body().string();
mHandler.post(new Runnable() {
public void run() {
mCallBack.onSuccess(re);
}
});
}
});
}//get
/**
* post方式进行网络访问
* @param url 地址
* @param data 回调
* @param mCallBack 接口
*/
public void post(String url,RequestBody data,final MOkCallBack mCallBack){
final Request request = new Request.Builder()
.url(url)
.header("cookie", cookie)
.post(data)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
mHandler.post(new Runnable() {
@Override
public void run() {
mCallBack.onError();
}
});
}
@Override
public void onResponse(final Response response) throws IOException {
cookie=response.header("set-cookie");
final String re=response.body().string();
mHandler.post(new Runnable() {
public void run() {
mCallBack.onSuccess(re);
}
});
}
});
}//post
/**
* 获取当前使用的cookie
* @return cookie
*/
public String getCookie() {
return cookie;
}
/**
* 设置下次访问网络的cookie,设置为""空文本则清除cookie
* @param cookie 要设置的cookie
*/
public void setCookie(String cookie) {
this.cookie = cookie;
}
/**
* 设置要不要自动跟随302重定向,默认为真
* @param followRedirects 是否自动跳转
*/
public void setFollowRedirects(boolean followRedirects) {
mOkHttpClient.setFollowRedirects(followRedirects);
}
}
使用方法:可以直接进行ui操作
uitls.get("http://www.baidu.com",new OkhttpUitls.MOkCallBack() {
@Override
public void onSuccess(String str) {
tv.setText(str);
Log.i("cookie","cookie->"+uitls.getCookie());
}
@Override
public void onError() {
tv.setText("error");
}
});
post方法比get多了一个data参数
RequestBody data=new FormEncodingBuilder()
.add("name", "android")
.add("psw", "123456")
.build();
如上构造键值对,然后传入就行。
在上传json数据时,data参数应该这样封装:
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody data = RequestBody.create(JSON, json);
最后附上okhttp的git项目原地址
https://github.com/square/okhttp