模拟OkHttp网络请求框架写一个自己网络请求库

文章目录

  • 前言
  • 一、OkHttp
  • 二、手写自己的网络请求框架
    • 1.构建网络请求
    • 2.设置请求队列,设置线程池
    • 3.设置线程从请求队列获取请求,提交到线程池执行请求
    • 4.将返回的数据进行解析,包装为实体类
  • 为了深入理解OkHttp源码,模仿OkHttp网络请求框架实现了一个简单的网络访问请求框架

前言

OKhttp是一个处理网络请求的开源项目,是安卓端最火热的轻量级框架

一、okhttp

使用及封装可参考http://blog.csdn.net/lmj623565791/article/details/47911083

二、实现自己的网络访问框架

1.构建访问请求

代码如下(示例):

/*请求接口类*/
public interface IHttpRequest {
    void setUrl(String url);
    void setData(byte[] data);
    void setListener(CallbackListener callbackListener);
    void execute();
}

import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/*json请求类*/

public class JsonHttpRequest implements IHttpRequest{
    private String url;
    private byte[] data;
    private CallbackListener callbackListener;
    @Override
    public void setUrl(String url) {
        this.url=url;
    }

    @Override
    public void setData(byte[] data) {
        this.data=data;
    }

    @Override
    public void setListener(CallbackListener callbackListener) {
        this.callbackListener=callbackListener;
    }
    private HttpURLConnection urlConnection;
    @Override
    public void execute() {
        //网络访问的具体操作
        URL url=null;
        try {
            url = new URL(this.url);
            urlConnection=(HttpURLConnection)url.openConnection();//打开http连接
            urlConnection.setConnectTimeout(6000);//连接超时时间
            urlConnection.setUseCaches(false);//不使用缓存
            urlConnection.setInstanceFollowRedirects(true);//是成员函数,用于当前函数,设置这个连接是否可以被重定向
            urlConnection.setReadTimeout(3000);//响应超时时间
            urlConnection.setDoInput(true);//设置这个连接是否可以被写入数据
            urlConnection.setDoOutput(true);//设置这个连接是否可以被输出数据
            urlConnection.setRequestMethod("POST");//设置请求的方式
            urlConnection.setRequestProperty("Content-Type","application/json;charset=UTF-8");//设置消息的类型
            urlConnection.connect();//连接,建立了一个与服务器的TCP连接
            //使用字节流发送数据
            OutputStream outputStream=urlConnection.getOutputStream();
            BufferedOutputStream bos=new BufferedOutputStream(outputStream);//缓存字节流包装字节流
            bos.write(data);//将这个字节流数组的数据写入缓存区中
            bos.flush();//刷新缓存区,发送数据
            outputStream.close();
            bos.close();
            //使用字节流写入数据
            if(urlConnection.getResponseCode()==HttpURLConnection.HTTP_OK){
                InputStream in=urlConnection.getInputStream();
                callbackListener.onSucess(in);
            }else{
                throw new RuntimeException("请求失败");
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            urlConnection.disconnect();
        }
    }
}
public class HttpTask<T> implements Runnable {
    IHttpRequest httpRequest;
    public HttpTask(String url,T requestData,IHttpRequest httpRequest,CallbackListener listener) {
        this.httpRequest=httpRequest;
        httpRequest.setUrl(url);
        httpRequest.setListener(listener);
        String content= JSON.toJSONString(requestData);
        try {
            httpRequest.setData(content.getBytes("utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        this.httpRequest.execute();
    }
}

2.创建线程池和请求队列

代码如下(示例):

//设置为单列模式
//1.准确请求队列,将请求添加到请求队列
//2.创建线程池,创建线程从队列中获取请求,将线程添加到线程池
public class ThreadPoolManger {
    private static ThreadPoolManger threadPoolManger=new ThreadPoolManger();
    //设置线程池
    private ThreadPoolExecutor threadPoolExecutor;
    public static ThreadPoolManger getInstance(){
        return threadPoolManger;
    }
    private ThreadPoolManger(){
        //线程池参数:核心线程数,最大线程数,存活时间,工作队列,拒绝策略
        threadPoolExecutor=new ThreadPoolExecutor(3, 10, 15,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(4), new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {
                addTask(runnable);
            }
        });
        //线程池处理线程
        threadPoolExecutor.execute(coreThread);
    }
    public Runnable coreThread=new Runnable() {
        Runnable run=null;
        @Override
        public void run() {
            while (true){
                //从请求队列中获取请求
                try {
                    run=mQueue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //采用线程池执行请求
                threadPoolExecutor.execute(run);
            }
        }
    };
    //设置请求队列
    private LinkedBlockingQueue<Runnable> mQueue=new LinkedBlockingQueue<>();
    //将请求添加到队列
    public void addTask(Runnable runnable)  {
        try {
            mQueue.put(runnable);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

3.解析响应数据

//将数据转化为实体数据
public class JsonCallbackListener<T> implements CallbackListener {
    //将返回数据转为实体数据
    private Class<T> responseClass;
    private IJsonDataListener iJsonDataListener;
    private Handler mHandler=new Handler(Looper.getMainLooper());
    public JsonCallbackListener(Class<T> responseClass,IJsonDataListener iJsonDataListener) {
        this.responseClass = responseClass;
        this.iJsonDataListener=iJsonDataListener;
    }

    @Override
    public void onSucess(InputStream inputStream) {
        //将输入流数据转化为String类型
        String response = getContent(inputStream);
        final T clazz= JSON.parseObject(response,responseClass);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
           iJsonDataListener.onSuccess(clazz);
            }
        });
    }

    private String getContent(InputStream inputStream) {
        String content = null;
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder sb = new StringBuilder();
            String line=null;
            try {
                while(((line=reader.readLine())!=null)){
                    sb.append(line+"\n");
                }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return content;
}
}

总结

public class MyOkHttp {
    public  static <T,M> void sendJsonRequest(T requestData,String url,Class<M> response,
                                              IJsonDataListener listener){
        IHttpRequest httpRequest=new JsonHttpRequest();
        CallbackListener callbackListener=new JsonCallbackListener<>(response,listener);
        HttpTask httpTask=new HttpTask(url,requestData,httpRequest,callbackListener);
        ThreadPoolManger.getInstance().addTask(httpTask);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_30193541/article/details/108174506