先上完整代码
package com.ysh.myapplication;
import android.os.Handler;
import android.os.Message;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class httpUtil {
private String url,method;
private HashMap<String,Long> params;
private Handler handler;
private int connectTimeout = 8000,readTimeout = 8000; //设置读取和连接超时时间 默认为8000
private boolean doInput = true, doOutput = true; //设置输入输出是否可用 输入默认为true 输出默认为true
public void setUrl(String url) {
this.url = url;
}
public void setMethod(String method) {
this.method = method;
}
public void setParams(HashMap<String, Long> params) {
this.params = params;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
public void setDoInput(boolean doInput) {
this.doInput = doInput;
}
public void setDoOutput(boolean doOutput) {
this.doOutput = doOutput;
}
private httpUtil(){}
private static httpUtil instance =new httpUtil();
public static httpUtil getInstance(){ //单例得到instance
if (instance == null) {
instance = new httpUtil();
}
return instance;
}
public static httpUtil.Builder getBuilder(){ //获得内部类Builder 用内部类太妙了 这样就不用写多个类 还有用的时候也不用新建builder 直接.url等等
return new Builder();
}
public static class Builder{ //内部类Builder 方便传递参数 设置方法,超时等等
private final httpUtil requestDirector= httpUtil.getInstance();
public Builder url(String url){
requestDirector.setUrl(url);
return this;
}
public Builder handler(Handler handler){
requestDirector.setHandler(handler);
return this;
}
public Builder params(HashMap<String,Long> params){
requestDirector.setParams(params);
return this;
}
public Builder method(String method){
requestDirector.setMethod(method);
return this;
}
public Builder connectTimeout(int connectTimeout){
requestDirector.setConnectTimeout(connectTimeout);
return this;
}
public Builder readTimeout(int readTimeout){
requestDirector.setReadTimeout(readTimeout);
return this;
}
public Builder doInput(Boolean doInput){
requestDirector.setDoInput(doInput);
return this;
}
public Builder doOutput(Boolean doOutput){
requestDirector.setDoOutput(doOutput);
return this;
}
public httpUtil build(){
return requestDirector;
}
}
public void sendPostRequest(){
ExecutorService pool= Executors.newFixedThreadPool(5); //线程池 设置最多有5个线程
pool.execute(new Runnable() {
@Override
public void run() {
try{
URL mUrl=new URL(url);
HttpURLConnection connection=(HttpURLConnection)mUrl.openConnection();
connection.setRequestMethod(method); //post or get
connection.setConnectTimeout(connectTimeout); //连接超时
connection.setReadTimeout(readTimeout); //读取超时
connection.setDoInput(doInput);
connection.setDoOutput(doOutput);
StringBuilder datatowrite=new StringBuilder();
for(String key :params.keySet()){
datatowrite.append(key).append("=").append(params.get(key)).append("&");
}
connection.connect();
OutputStream outputStream=connection.getOutputStream();
outputStream.write(datatowrite.substring(0,datatowrite.length()-1).getBytes());
InputStream in=connection.getInputStream();
String respondata =StreamToString(in);
Message message=new Message();
message.obj=respondata;
handler.sendMessage(message);
}catch (Exception e){
e.printStackTrace();
}
}
});
}
public String StreamToString(InputStream in){
StringBuilder sb=new StringBuilder();
String oneline;
BufferedReader reader=new BufferedReader(new InputStreamReader(in));
try{
while((oneline=reader.readLine())!=null){
sb.append(oneline).append('\n');
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
in.close();
}catch (IOException e){
e.printStackTrace();
}
}
return sb.toString();
}
}
建造者模式
如果你不知道什么是建造者模式,那可以先参考这篇文章,他讲的肯定比我讲的清楚。但是我看完之后,我最初的感觉是很疑惑,建造者是让使用者不需要知道步骤就得到复杂类,但我们得到的是Gson字段,但不同的Gson字段都有它自己特有的属性,那不是很奇怪吗?现在想想自己也是蛮蠢的,因为复杂类里面的属性,不是Gson字段里的信息,而是构建Gson的参数,比如url,parms,post,get等等,就像那篇文章中的Meal类,food和drink属性,我想当然的认为这是得到meal类后的属性,其实它们是构建Meal的参数,meal由它们组成,应该这样理解,这样理解之后就感觉豁然开朗hhh
作用
类比于你去餐馆点餐,你选择了你需要的菜(复杂类),并告诉了服务员(Director指挥者),于是服务员到后台告诉厨师(Builder)你需要的菜,最后厨师做好后由服务员端上来,然后你吃掉,但在这一过程中,厨师长什么样子,他是怎么做出这道菜的,这些细节你都没有看到过,这就是服务员(Director)的作用,隔离了客户与对象的生产过程,而服务员还要负责去监督后厨工作,比如厨房里的人数,同时有多少个灶台,这就要和 线程池 有关系了,这也是服务员(Director)的另一个作用,负责控制产品对象的生产过程。
线程池
很简单,一个人要做很多事情,一丶想到什么就做什么。二丶找其他人帮忙一起做,或者制作一张时间表,有规划的做。
那么 一和二 哪个效率更高呢,很显然,第二种明显更加高效,这就是线程池的作用,而线程池有四种
一、newSingleThreadExecutor(制作时间表)
这个线程池是单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
就像你制作了一张时间表,规划了一天的行程,那是不是效率更高了呢
注:适合于个人独自偷学时用(单线程)
二、newFixedThreadPool(找小伙伴帮忙)
在遇到事情很多忙不过来时,找小伙伴帮忙肯定是一种很好的方式,人多力量大,分工合作一定比一个人干效率高
注:适合于团伙作案(多线程)
三、newScheduledThreadPool(设置闹钟提醒)
创建一个可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。
四、newCachedThreadPoo (流水线生产)
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
单例模式
场景:我们需要用钱(内存)去雇佣一个人(创建对象),所以我们在小区公告栏里贴了一张广告,表示我们需要这样一个人,但是有两个人同时看到了这个广告并找到我们,表示他能够胜任,当然在现实中,我们肯定只需要一个人,否则就需要双倍的钱去干同一件事情,亏死!
但是在计算机中我们如何做到防止亏内存呢 所以我们就需要单例模式来防止开双倍工资亏钱!
单例类的作用:让一个类只能创建一个实例(因为频繁的创建对象,回收对象会造成系统性能下降。)。解决对象的唯一性,保证了内存中一个对象是唯一的 。
使用单例类条件:当前对象的创建比较消耗资源,我们在使用这个对象时只需要有一个就可以应用