搜索
您的当前位置:首页正文

网络架构之自定义Valloy

来源:二三娱乐

应用到知识点

  • 需求:
    支持请求 JSON文本类型,音频,图片类型,批量下载。上传
    请求各种 数据时,调用层不关心上传参数分装,如(request.addParamas(key,value))
    直接将参数分装成对象,传给框架
    获取数据后 调用层不关心JSON数据解析
    回调时 调用层只需要知道传入的JSON的对应的响应类。
    回调响应结果发生在主线程(线程切换)
    对下载,上传扩展
    支持高并发请求,请求队列依次获取,可以设置最大并发数,设置先请求先执

  • 会用到的知识点
    泛型
    请求队列
    阻塞队列
    线程池拒绝策略
  • 设计模式
    模板方法模式
    单例模式
    策略模式
    生产者消费者模式
Paste_Image.png

流程步骤

1、客户端请求

 public void login(View view) {
        User user = new User();
        user.setName("13343491234");
        user.setPassword("123456");
        for (int i = 0; i < 50; i++) {
            Volley.sendRequest(user, url, LoginRespense.class, new 
IDataListener<LoginRespense>() {
                @Override
                public void onSuccess(LoginRespense loginRespense) {
                    Log.i(TAG, loginRespense.toString());
                }

                @Override
                public void onFail() {
                    Log.i(TAG, "获取失败");
                }
            });
        }
    }

2、封装请求参数并添加任务到线程池

请求参数


public class Volley {
    /**
     * @param <T> 请求参数类型
     * @param <M> 响应参数类型
     *            暴露给调用层
     */
   public static <T, M> void sendRequest(T requestInfo, String url,
                                          Class<M> response, IDataListener dataListener) {
        RequestHodler<T> requestHodler = new RequestHodler<>();
        requestHodler.setUrl(url);
        //执行http接口实现类
        IHttpService httpService = new JsonHttpService();
        //回调接口
        IHttpListener httpListener = new JsonDealLitener<>(response, dataListener);
        requestHodler.setHttpService(httpService);
        requestHodler.setHttpListener(httpListener);
        HttpTask<T> httpTask = new HttpTask<>(requestHodler);
        try {
            ThreadPoolManager.getInstance().execte(new FutureTask<Object>(httpTask, null));
        } catch (InterruptedException e) {
            dataListener.onFail();
        }
    }

3、线程池管理任务

将任务添加到线程池,这里用户到了阻塞队列实现高并发。

public class ThreadPoolManager {
    private static final String TAG = "ThreadPoolManager";
    private static ThreadPoolManager instance = new ThreadPoolManager();
    //阻塞队列
    private LinkedBlockingQueue<Future<?>> taskQuene = new LinkedBlockingQueue<>();

    //线程池类,添加FutureTask任务
    private ThreadPoolExecutor threadPoolExecutor;

    public static ThreadPoolManager getInstance() {
        return instance;
    }

    private ThreadPoolManager() {
        threadPoolExecutor = new ThreadPoolExecutor(4, 10, 10, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(4), handler);
        threadPoolExecutor.execute(runable);
    }


    private Runnable runable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                FutureTask futrueTask = null;
                try {
                    /**
                     * 阻塞式函数
                     */
                    Log.i(TAG, "等待队列     " + taskQuene.size());
                    futrueTask = (FutureTask) taskQuene.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (futrueTask != null) {
                    threadPoolExecutor.execute(futrueTask);
                }
                Log.i(TAG, "线程池大小      " + threadPoolExecutor.getPoolSize());
            }
        }
    };

    public <T> void execte(FutureTask<T> futureTask) throws InterruptedException {
        taskQuene.put(futureTask);
    }

    //当线程池满的时候回调用RejectedExecutionHandler类的rejectedExecution方法,将任务添加的任务队列
    private RejectedExecutionHandler handler = new RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            try {
                taskQuene.put(new FutureTask<Object>(r, null) {
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
}

4、网络请求和响应

第三步将任务HttpTask添加到线程池中,该类的网络请求及响应的接口分别是IHttpServiceIHttpListener。前者用于执行网络请求,后者用于处理响应并且将响应信息回传给调用者。

  • 网络请求
public class JsonHttpService implements IHttpService {
    private IHttpListener httpListener;

    private HttpClient httpClient=new DefaultHttpClient();
    private HttpPost httpPost;
    private String url;

    private byte[] requestDate;
    /**
     * httpClient获取网络的回调
     */
    private HttpRespnceHandler httpRespnceHandler=new HttpRespnceHandler();
    @Override
    public void setUrl(String url) {
        this.url=url;
    }

    @Override
    public void excute() {
        httpPost=new HttpPost(url);
        ByteArrayEntity byteArrayEntity=new ByteArrayEntity(requestDate);
        httpPost.setEntity(byteArrayEntity);
        try {
            httpClient.execute(httpPost,httpRespnceHandler);
        } catch (IOException e) {
            httpListener.onFail();
        }
    }

    @Override
    public void setHttpListener(IHttpListener httpListener) {
        this.httpListener=httpListener;
    }

    @Override
    public void setRequestData(byte[] requestData) {
         this.requestDate=requestData;
    }
    private class HttpRespnceHandler extends BasicResponseHandler
    {
        @Override
        public String handleResponse(HttpResponse response) 
throws ClientProtocolException {
            //响应吗
            int code=response.getStatusLine().getStatusCode();
            if(code==200)
            {
                httpListener.onSuccess(response.getEntity());
            }else
            {
                httpListener.onFail();
            }


            return null;
        }
    }
}
  • 网络响应
    由于任务执行是在子线程,调用者(Activity)一般在主线程更新UI,所以要进行线程切换。这里要使用主线程的Handler,通过post方法执行客户端回调接口IDataListener进行数据传递。
public class JsonDealLitener<M> implements IHttpListener {
    private Class<M> responese;
    /**
     * 回调调用层 的接口
     */
    private IDataListener<M> dataListener;

    Handler handler=new Handler(Looper.getMainLooper());
    public JsonDealLitener(Class<M> responese, IDataListener<M> dataListener) {
        this.responese = responese;
        this.dataListener = dataListener;
    }

    @Override
    public void onSuccess(HttpEntity httpEntity) {
        InputStream inputStream=null;
        try {
            inputStream=httpEntity.getContent();
            /*
            得到网络返回的数据
            子线程
             */
            String content=getContent(inputStream);
            final M m= JSON.parseObject(content,responese);

            handler.post(new Runnable() {
                @Override
                public void run() {
                    dataListener.onSuccess(m);
                }
            });
        } catch (IOException e) {
            dataListener.onFail();
        }

    }

    @Override
    public void onFail() {
        dataListener.onFail();
    }
    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 (IOException e) {
                dataListener.onFail();
                System.out.println("Error=" + e.toString());
            } finally {

                try {
                    inputStream.close();
                } catch (IOException e) {
                    System.out.println("Error=" + e.toString());
                }
            }
            return sb.toString();

        } catch (Exception e) {
            e.printStackTrace();
            dataListener.onFail();
        }
        return content;
    }
}

Top