Android网络优化4--写一个网络请求模板

我们在开发的时候,基本都需要写一些网络请求的模块。
下面是一个模板代码,可以直接复制过去使用。

流程介绍:

我们申请一个线程池,便于控制网络请求。
把网络的请求的具体内容写到Runnable中去,然后传递给我们的ThreadPoolUtils去执行。

先看下我们的Activity吧。

public class HttpDemoActivity extends Activity {    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //在线程中执行这个获取XXX的task
        ThreadPoolUtils.execute(new MyGetXXXRunnableTask());
    }
}

好了,我们的demo基本就长这样子咯。

那么我们的MyGetXXXRunnableTask就是这样啦。

MyGetXXXRunnableTask

public class MyGetXXXRunnableTask implements Runnable{

    private String paraX;   
    public  MyGetXXXRunnableTask( String paraX){ 
        this.paraX = paraX;
    }        

    @Override
    public void run() {            
        HttpGet httpGet = new HttpGet("某个地址");             
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params, 60000);
        httpGet.setParams(params);
         try {                
            HttpResponse httpResponse = HttpClientHelper.getHttpClient().execute(httpGet);                
            byte[] bytes = EntityUtils.toByteArray(httpResponse.getEntity());

            String result = new String(bytes);                
            Log.i(TAG,"hi,i get "+result);                

        } catch (Exception ex){
            ex.printStackTrace(); 
        }
    }
}

需要注意的一句是HttpResponse httpResponse = HttpClientHelper.getHttpClient().execute(httpGet);
是的啦,就是这样,我们用一个单例的helper去执行我们的网络请求.
具体如下

HttpClientHelper

public class HttpClientHelper {
    private static HttpClient httpClient;       
    private HttpClientHelper(){}

    public static synchronized HttpClient getHttpClient(){
        if(null == httpClient){ 
            HttpParams params = new BasicHttpParams();              
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
            HttpProtocolParams.setUseExpectContinue(params, true);  
            ConnManagerParams.setTimeout(params, 1000);              
            HttpConnectionParams.setConnectionTimeout(params, 5000); 
            HttpConnectionParams.setSoTimeout(params, 10000);

            SchemeRegistry schReg = new SchemeRegistry();
            schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 80));              
            ClientConnectionManager conManager = new ThreadSafeClientConnManager(params, schReg);

            httpClient = new DefaultHttpClient(conManager, params);
        }                       
        return httpClient;
    }
}

最后就是我们的ThreadPoolUtil类
线程池辅助类,可以设置核心线程数、最大线程数、额外线程空状态生存时间,阻塞队列长度来优化线程池。

ThreadPoolUtils

public class ThreadPoolUtils {      
    private ThreadPoolUtils(){}

    //线程池核心线程数
    private static int CORE_POOL_SIZE = 5;      
    //线程池最大线程数
    private static int MAX_POOL_SIZE = 100;     
    //额外线程空状态生存时间
    private static int KEEP_ALIVE_TIME = 10000;     
    //阻塞队列。当核心线程都被占用,且阻塞队列已满的情况下,才会开启额外线程。
    private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(10);        

    //线程工厂
    private static ThreadFactory threadFactory = new ThreadFactory() {
        private final AtomicInteger integer = new AtomicInteger();  
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "myThreadPool thread:" + integer.getAndIncrement());
        }
    };

    //线程池
    private static ThreadPoolExecutor threadPool;       
    static {
        threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE,
                MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue,
                threadFactory);
    }                

      //最重要的一句咯。
    public static void execute(Runnable runnable){
        threadPool.execute(runnable);
    }

}

好啦,模板的一个网络请求写到这里,需要小结一下咯。

问题

1.返回结果

有什么问题?你没发觉好像没有返回结果给我们的调用吗??没有返回结果啊,真的没有啊?
怎么办?

  1. 可以使用EventBus来做这事!
  2. 加回调接口

2.线程池

不是任何程序都适合用线程池的,需要根据实际的业务来做。

什么时候不适合呢?

  1. 如果需要使一个任务具有特定优先级,对此建议使用具有优先级配置的任务队列来做。
  2. 如果具有可能会长时间运行(并因此阻塞其他任务)的任务。
  3. 如果需要将线程放置到单线程单元中(线程池中的线程均处于多线程单元中)。
  4. 如果需要永久标识来标识和控制线程,比如想使用专用线程来终止该线程,将其挂起或按名称发现它

那些情况下合适?

  1. 需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。 但对于长时间的任务,比如一个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
    对于这个案例情景,推荐使用谷歌的Volley,因为它的设计就是针对高频数据量小的业务而做的。
    可以看下这篇文章了解下:Android网络访问解决方案小结·1
    这里写图片描述
  2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
  3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,并出现”OutOfMemory”的错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值