赠送 HttpClient 和HttpURLConnection 的轻型网络 --》线程池介绍和网络请求流程

转载注明出处 :http://blog.csdn.net/codingandroid/article/details/41748743

作为一个框架,肯定要去处理一些比较复杂的情况,正常情况下当然不会阻塞,当情况比较复杂的时候,会出现前多个网络请求的情况,那对于这种情况我们规范去管理当然是最好的了,于是我们需要一个线程池。

首先解释一下,什么叫线程池  :

每当启动一个线程的时候,我们通常代码是   new Thead(){}.start();  new 一个对象 里面又要new一个runnable 这个是相对比较耗时的,资源我们能省就省,这个线程池就相当与说:我维护一个池子,例如里面放5个现成的线程,请求来了也不用重新去new 直接就能使用,超过5个的时候需要等待一下    对android的开发的来说  就类似于 soundpool吧

理解这个就好,代码没几行,放上来哦

package com.clxu.netframe.abstractinterface;

import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/***
 * @function  线程池
 * @author CLXU
 *
 * 2014-11-25
 */
public class DefaultThreadPool {
    /**
     * 用于保存等待执行的任务的阻塞队列。(有序的先进先出阻塞队列)
     */
    private static ArrayBlockingQueue<Runnable> mBlockingQueue = new ArrayBlockingQueue<Runnable>(15, true);

    /**
     * 线程池
     */
    private static AbstractExecutorService mThreadPoolExecutor
                                                        = new ThreadPoolExecutor(5, 7, 25, TimeUnit.SECONDS, mBlockingQueue,
                                                                new ThreadPoolExecutor.DiscardOldestPolicy());

    private static DefaultThreadPool instance = null;

    public static DefaultThreadPool getInstance() {
        if (instance == null) {
            instance = new DefaultThreadPool();
        }
        return instance;
    }

    /**
     * 执行任务
     * @param r
     */
    public void execute(Runnable r) {
        mThreadPoolExecutor.execute(r);
    }

    /**
     * 关闭,并等待任务执行完成,不接受新任务
     */
    public static void shutdown() {
        if (mThreadPoolExecutor != null) {
            mThreadPoolExecutor.shutdown();
        }
    }

    /**
     * 关闭,立即关闭,并挂起所有正在执行的线程,不接受新任务
     */
    public static void shutdownRightnow() {
        if (mThreadPoolExecutor != null) {
            mThreadPoolExecutor.shutdownNow();
            try {
                // 设置超时极短,强制关闭所有任务
                mThreadPoolExecutor.awaitTermination(1, TimeUnit.MICROSECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

上一篇中使用的时候有一句代码   mDefaultThreadPool.execute(asyncBaseRequest);那就是线程池了,不过下面那个是什么呢?

mAsyncRequests.add(asyncBaseRequest);这行的代码的作用是 维护当前的 activity的所有的请求,当前页面关闭的时候,方便结束掉所有的请求

这里面有涉及一个基本的请求类   AsyncBaseRequest 这个类,这个是个请求的基类,在里面我们设定网络请求的各个流程,以及对异常的处理

package com.clxu.netframe.abstractinterface;

import java.io.IOException;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpHostConnectException;

import com.clxu.netframe.R;
import com.clxu.netframe.constant.Constant;
import com.clxu.netframe.exception.MyException;
import com.clxu.netframe.net.callback.ParseCallback;
import com.clxu.netframe.net.callback.ResultCallback;
import com.clxu.netframe.util.LogUtil;

/**
 * 功能描述:网络请求线程基类
 * @author clxu
 * 创建日期:2014-12-4
 */
public abstract class AsyncBaseRequest implements Runnable, Serializable {
    private static final long serialVersionUID = 1L;
    /** LOG打印标签*/
    private static final String TAG = "AsyncBaseRequest";
    /** 网络连接超时,默认值为10秒*/
    protected int connectTimeout = 10 * 1000;
    /** 网络数据读取超时,默认值为10秒*/
    protected int readTimeout = 10* 1000;
    private boolean interrupted;
    public boolean isInterrupted() {
        return interrupted;
    }

    public void setInterrupted(boolean interrupted) {
        this.interrupted = interrupted;
    }

    protected void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    protected void setReadTimeout(int readTimeout) {
        this.readTimeout = readTimeout;
    }

    protected String requestUrl;
    protected Map<String, String> parameter;
    private ParseCallback parseHandler;
    private ResultCallback requestCallback;
    protected HttpURLConnection mHttpURLConn;
    protected String mInStream;
    private MyException ex;

    public AsyncBaseRequest(String url, Map<String, String> parameter, ParseCallback handler, ResultCallback requestCallback) {
        this.parseHandler = handler;
        this.requestUrl = url;
        this.parameter = parameter;
        this.requestCallback = requestCallback;
    }

    /**
     * 发送网络请求
     * @return 网络请求返回的InputStream数据流
     * @throws Exception
     */
    protected abstract String getRequestResult() throws Exception;

    @Override
    public void run() {
        if (interrupted) {
            LogUtil.i(TAG, "访问网络前中断业务处理线程(终止)");
            return;
        }

        try {
        	//访问网络,获取到返回数据
            mInStream = getRequestResult();
            if (mInStream != null) {
                Object obj = null;
                if(parseHandler != null){
                	//回调 数据解析接口
                    obj = parseHandler.parse(mInStream);
                }
                if(requestCallback!=null){
                    requestCallback.onSuccess(obj);
                }

            } else {
                LogUtil.e(TAG, "get InputStream By HttpURLConnection return result is NULL.");
                ex = new MyException(R.string.network_request_fail, Constant.NETWORK_REQUEST_RETUN_NULL, R.string.network_request_return_null);
                requestCallback.onFail(ex); // 网络请求返回NULL
            }
        }catch(SocketTimeoutException e){
        	//SocketTimeoutException 这个超时异常是说明请求已经到达服务器,返回数据过程中超时了,如果是订单类的请求要注意了,需要防止重复提交
            ex = new MyException(e);
            requestCallback.onFail(ex);
		}catch(ConnectTimeoutException e){
			//ConnectTimeoutException 这个是连接异常(例如根本没有打开网络等情况下),数据还没有到达服务器,所以就算是订单类的也没有关系,可以再次提交
            ex = new MyException(e);
            requestCallback.onFail(ex);
		}catch (TimeoutException e) {
			//TimeoutException 这个是总的超时异常,这里还是捕捉一下
            ex = new MyException(e);
            requestCallback.onFail(ex); // IO异常标识
		}catch (HttpHostConnectException e) {
			//HttpHostConnectException 出现这个异常,检查程序是否添加网络权限
            ex = new MyException(e);
            requestCallback.onFail(ex);
		}catch (IOException e) {
            ex = new MyException(e);
            requestCallback.onFail(ex); // IO异常标识
        } catch (Exception e) {
            ex = new MyException(e);
            requestCallback.onFail(ex); // 未知异常标识
        }

    }

    public HttpURLConnection getRequestConn() {
        return mHttpURLConn;
    }

}

当然,需要两个接口

package com.clxu.netframe.net.callback;

import org.json.JSONException;

/***
 * @function 网络请求返回的数据解析接口
 * @author CLXU
 * 2014-11-25
 */
public interface ParseCallback {
    /**
     * 对网络请求返回的数据进行解析
     * @param json  要解析的字符串,JSON格式
     * @return 解析的结果
     * @throws JSONException JSON异常(普通字符串转换成JSON字符串时,格式出错会抛此异常)
     */
	public Object parse(String json) throws JSONException;

}
package com.clxu.netframe.net.callback;

import com.clxu.netframe.exception.MyException;

/**
 * 功能描述:网络请求返回的结果回调接口
 * <span style="font-family: Arial, Helvetica, sans-serif;">@author CLXU</span>
 * 创建日期:2014-11-19
 */
public interface ResultCallback {
    public void onSuccess(Object obj);

    public void onFail(MyException e);

}

框架源码下载地址:http://download.csdn.net/detail/brightshadow11111/8228287

时间: 2024-10-05 04:28:01

赠送 HttpClient 和HttpURLConnection 的轻型网络 --》线程池介绍和网络请求流程的相关文章

赠送 HttpClient 和HttpURLConnection 的轻型网络 ---》按照自己的需求定制修改框架

转载注明出处:http://blog.csdn.net/codingandroid/article/details/41801309 这个最后一节,我这里会总体的介绍一下这个项目的各个类的作用,以及使用过程中可以对它进行的一些扩展定制,以满足自己应用开发的需求. 我们从下往上面看  LogUtil 这个类看名字就知道是个日志工具类,不多说,看了就明白 com.clxu.netframe.netbase 这个是我自己尝试去用socket封装Urlconnection,目前问题还比较多,没有放出来,

赠送 HttpClient 和HttpURLConnection 的轻型网络 ---》框架使用介绍

转载注明出处:http://blog.csdn.net/codingandroid/article/details/41748007 之前看网上的一些网络框架,多少存在一些bug,大多还没有源码,有些有源码,框架过于太大,发现了bug修改起来也实在费事,所以使用自己的网络框架是最佳选择哦,这个框架我这里有借鉴一些其他框架的地方,不过提供功能就是   post  请求网络. Android使用 HttpClient 和 HttpURLConnection,当然他们都存在一些缺陷,自己通过socke

赠送 HttpClient 和HttpURLConnection 的轻型网络 ---》常见异常分析

转载注明出处 :http://blog.csdn.net/codingandroid/article/details/41749581 之前一篇中有使用到AsyncBaseRequest 类,其中抛出了很多异常,当然已经有了部分注释,那下面我们来分析一下这些异常,以及异常出现的情况 ConnectTimeoutException 这个是连接异常(例如根本没有打开网络等情况下),数据还没有到达服务器,所以就算是订单类的也没有关系,可以再次提交 这个情况比较好处理了,就是请求压根没到服务器,如果要模

Java线程池介绍

Java线程池介绍 2015-10-24 ImportNew (点击上方公号,可快速关注) 原文:allegro 译文:ImportNew - paddx 链接:http://www.importnew.com/16845.html 根据摩尔定律(Moore’s law),集成电路晶体管的数量差不多每两年就会翻一倍.但是晶体管数量指数级的增长不一定会导致 CPU 性能的指数级增长.处理器制造商花了很多年来提高时钟频率和指令并行.在新一代的处理器上,单线程程序的执行速率确实有所提高.但是,时钟频率

简易“线程池”在Python网络爬虫中的应用

一,我是如何使用Python抓取网页的 我知道Python有一个爬虫框架scrapy,但是目前还没有学习,并且也没有什么很棘手的的问题需要去使用一个爬虫框架,所以我就用Python自带的urllib,将目标网页爬下来,然后用正则过滤出自己需要的内容. 二,效率问题 上面的方法简单,真的是上手即用,但是问题是效率问题,如果一个网页一个网页的抓,显然带宽无法达到最高,浪费了大部分带宽,这时候大部分人都会想到,多线程啊! 对,但是我们大部分人又都会写出下面的代码 # 总任务数有500个 while i

java线程池介绍与使用

在同等数量级的操作下,使用线程池的效率要远远高于单线程.线程池可以降低创建线程带来的开销.而线程池中的线程结束后进行的是回收操作而不真的将线程销毁.而在这个过程过,线程池带来的内存消耗肯定会大于单线程.在使用线程池的时候要慎重这个问题.下面进行两个方法,分别来测试下. import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.LinkedBloc

java 的线程池介绍

参考文献: http://www.jianshu.com/p/87bff5cc8d8c http://www.jianshu.com/p/edd7cb4eafa0 在Java应用中如果需要频繁的去创建大量线程去完成任务,肯定会对性能有很大的影响.因为系统在创建和销毁线程上需要消耗太多的资源,开销很大. 所以在这种情况下可以考虑线程池.有以下优点: 1) 降低资源消耗 :通过重复利用已创建的线程降低线程创建和销毁造成的消耗: 2)提高响应速度 : 当任务到达时,任务可以不需要等到线程创建就能立即执

Qemu线程池介绍

有时我们希望把一部分工作通过创建线程的方式异步执行,这样我们可以在执行任务的同时,继续执行其他任务.但是如果这种需求比较多的话,频繁的创建和销毁线程带来很大的性能损耗.如果我们能创建一个或一些线程,然后重复使用它们,就可以避免这个问题. Qemu的实现 qemu模仿glib实现了线程池的功能,目前qemu中线程池主要应用在raw文件的支持上,当linux-aio不可用时,就像glibc,通过线程实现aio机制.我们也可看到,代表线程池中的线程成员的数据结构 ThreadPoolElement 就

FFMPEG Tips (4) 如何中断阻塞的网络线程

本文是我的<FFMPEG Tips>系列的第四篇文章,前面的文章有提到如何提取码流信息.如何读每一帧的数据,这些都是离不开网络操作,例如:使用 ffmpeg 读取一个码流,常规的代码流程示例如下: AVFormatContext *ic = avformat_alloc_context(); if (avformat_open_input(&ic, url, NULL, NULL) < 0) {     return -1; } if (avformat_find_stream_