OKHTTP的简单封装
程序员文章站
2024-03-25 11:33:04
...
前言
我们常用的网络框架大致有三个:Xutils,Volly,和OKhttp,前两个随着谷歌对OKhttp的推出基本上被取代了,既然被取代了,就肯定有它们的不足。
Xutils:博而不精,它包含的功能很多,像网络请求,加载图片,注解,数据库。。。这些导致它的包非常大,并且对我们框架的更新也比较困难。
Volly:速度快,但是不支持下载大文件,这个局限也就约束它的使用范围,以及框架的广度。
OKhttp:减少对服务器的请求次数,减少请求延迟,减少数据流量,缓存响应数据等来减少重复的网络请求,自动处理GZip压缩等,
但是OKhttp也不是没有缺点,那就是:实现代码比较多,并且传回来的消息需要切到主线程,而主线程要自己去写。传入调用比较复杂所以这里写了一个工具类进行简单的封装
封装的功能
使用Handler实现子线程和主线程之间的交互
定义三个接口调用分别返回String,byte[],和JSONObject
同时在支持表单提交Post 请求
复用Handler而不是一直实例化
依赖
使用之前当然是要导入依赖以及使用的网络权限
依赖
// 导入OK的网络请求框架
compile 'com.squareup.okhttp3:okhttp-ws:3.4.2'
网络权限
<!--加入网络权限-->
<uses-permission android:name="android.permission.INTERNET"/>
工具类
import android.os.Handler;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Map;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* 尝试简单封装一下OKhttp
*/
public class OKhttpManager {
//定义成员变量
private OkHttpClient mClient;
private volatile static OKhttpManager sManager;//防止多个线程同时访问
private static Handler handler;//开启线程交互 这里的handler 是os包下面的
// 使用构造方法,完成初始化
public OKhttpManager() {
mClient=new OkHttpClient();
handler=new Handler();
}
// 使用单例模式,通过获取的方式拿到对象
public static OKhttpManager getInstance(){
OKhttpManager instance=null;
if (sManager==null){
synchronized (OKhttpManager.class){
if (instance==null){
instance=new OKhttpManager();
sManager=instance;
}
}
}
return instance;
}
// 定义要调用的接口
interface Func1{
void onResponse(String result);
}
interface Func2{
void onResponse(byte [] result);
}
interface Func3{
void onResponse(JSONObject jsonObject);
}
// 使编写的代码运行在主线程
// 处理请求网络成功的方法,返回的结果是Json串
private static void onSuccessJsonStringMethod(final String jsonValue, final Func1 callBack){
handler.post(new Runnable() {
@Override
public void run() {
if (callBack!=null){
try {
callBack.onResponse(jsonValue);
}catch (Exception e){
e.printStackTrace();
}
}
}
});
}
/**
* 返回响应的结果是Json对象
* @param jsonValue
* @param callBack
*/
private void onSuccessJsonObjectMethod(final String jsonValue, final Func3 callBack){
handler.post(new Runnable() {
@Override
public void run() {
if (callBack!=null){
try{
callBack.onResponse(new JSONObject(jsonValue));
}catch(JSONException e){
e.printStackTrace();
}
}
}
});
}
/**
* 返回响应的结果是byte[]数组
* @param data
* @param callBack
*/
private void onSuccessByteMethod(final byte[] data,final Func2 callBack){
handler.post(new Runnable() {
@Override
public void run() {
if (callBack!=null){
callBack.onResponse(data);
}
}
});
}
// 然后是调用方法
/**
* 请求指定的url返回的结果是Json
* @param url
* @param callBack
*/
public void asyncJsonStringByURL(String url,final Func1 callBack){
final Request request = new Request.Builder().url(url).build();
mClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
if (response!=null&&response.isSuccessful()){
onSuccessJsonStringMethod(response.body().string(),callBack);
}
}
});
}
/**
* 请求返回的是json对象
*
* @param url
* @param callBack
*/
public void asyncJsonObjectByURL(String url, final Func3 callBack) {
final Request request = new Request.Builder().url(url).build();
mClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSuccessJsonObjectMethod(response.body().string(), callBack);
}
}
});
}
/**
* 请求返回的是byte字节数组
*/
public void asyncGetByteByURL(String url, final Func2 callBack) {
final Request request = new Request.Builder().url(url).build();
mClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
if (response != null && response.isSuccessful()) {
onSuccessByteMethod(response.body().bytes(), callBack);
}
}
});
}
// 表单提交像一般的姓名和密码
/**
* 表单提交
* @param url
* @param params
* @param callBack
*/
public void sendComplexForm(String url, Map<String,String> params,final Func1 callBack){
FormBody.Builder form_builder=new FormBody.Builder();//表单对象包含以input开始的对象以html为主
// 非空键值对
if (params != null && !params.isEmpty()) {
for(Map.Entry<String,String> entry : params.entrySet()){
form_builder.add(entry.getKey(),entry.getValue());
}
}
RequestBody request_body = form_builder.build();
Request request = new Request.Builder().url(url).post(request_body).build();//采用post方式提交
mClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
if (response!=null&&response.isSuccessful()){
onSuccessJsonStringMethod(response.body().string(), callBack);
}
}
});
}
}
以上就是工具类,用时直接复制粘贴到我们的工具类里面即可,
那如何调用呢?
其实调用也很简单,只需简单实例化
private OKhttpManager manager = OKhttpManager.getInstance();
然后简单调用即可
在业务代码里
package jingou.jo.com.tryfengzhuangokhttp;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.util.HashMap;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.json)
Button json;
@BindView(R.id.table)
Button table;
@BindView(R.id.pic)
Button pic;
@BindView(R.id.imgs)
ImageView imageView;
// 使用封装后的OKhttp,所定义的成员变量
private OKhttpManager manager = OKhttpManager.getInstance();
private String json_path="http://apiv4.yangkeduo.com/subject_collection/18?pdduid=";
private String pic_path="http://imgsrc.baidu.com/image/c0%3Dshijue1%2C0%2C0%2C294%2C40/sign=3d2175db3cd3d539d530078052ee8325/b7003af33a87e950c1e1a6491a385343fbf2b425.jpg";
private String post_path="http://blog.csdn.net/qiaoshi96_bk/article/details/77371035";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
//设置点击事件
@OnClick({R.id.json, R.id.table, R.id.pic})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.json:
//这里调用获取网络Json串封装的方法
manager.asyncJsonStringByURL(json_path, new OKhttpManager.Func1() {
@Override
public void onResponse(String result) {
Log.e("TAG",result);
}
});
break;
case R.id.table:
// 表单提交的方法向服务器提交账号或者是密码
final HashMap<String, String> map = new HashMap<>();
map.put("qs","1008611");
manager.sendComplexForm(post_path,map, new OKhttpManager.Func1() {
@Override
public void onResponse(String result) {
Log.e("TAG"+map.getClass().getName(),result);
}
});
break;
case R.id.pic:
// 获取图片使用Bitmap加载
manager.asyncGetByteByURL(pic_path, new OKhttpManager.Func2() {
@Override
public void onResponse(byte[] result) {
Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
imageView.setImageBitmap(bitmap);
}
});
break;
}
}
}
这里的我是通过注解来实现获取id的非常好用贴上它的依赖:Butterknife(黄油刀)
// 查找id的依赖
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
具体用法:http://blog.csdn.net/qiaoshi96_bk/article/details/77371035
效果如下