OkHttp封装,支持缓存,Gzip,文件上传,文件下载,Json分批加载

 * 
 * 
 * 1 支持没网缓存,和保质期(多少秒之内不请求后台,而是读缓存)
 * 
 * 2 支持强制读取缓存
 * 
 * 3 支持删除整个缓存和某个接口缓存
 * 
 * 4 支持大文件下载
 * 
 * 5 支持单个接口配置缓存,保质期,连接时间
 * 
 * 6 支持Gzip压缩,解决了Gzip缓存乱码bug

 * 7 支持分批读取json数组,不会oom

 * 8 支持文件上传,和下载

  

需要 okhttp-3.4.1 jar包及以上

最新okhttp jar包链接:http://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp/3.6.0

最新 ok.io  jar包链接:http://mvnrepository.com/artifact/com.squareup.okio/okio/1.11.0

使用方法:

// 测试缓存
public static void testCache(ObserverCallBack back) {
       String url = "http://118.25.43.50:8089/sv/operation/operation/main.do";
       HashMap<String, Object> config = new HashMap<String, Object>();
       config.put(HttpConfig.MAX_AGE, 60 * 5);// 5分钟之内不走网络走缓存
       config.put(HttpConfig.MAX_STALE, 60 * 60 * 24 * 2);// 没网时数据缓存两天
       // config.put(HttpConfig.CONNECT_TIME, 30);//超时时间30秒
       OkHttpUtil.get(url, back, -1, null, config);
}

// 测试读取缓存
public static void readCache() {
       String url = "http://118.25.43.50:8089/sv/operation/operation/main.do";
       // 为null说明没数据
       String response = OkHttpUtil.getCacheResponse(url);
       System.out.println("读取本地缓存:" + response);
}



import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import okhttp3.Cache;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.FormBody.Builder;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.internal.Util;
import okio.BufferedSink;
import okio.GzipSink;
import okio.Okio;

/**
 * okhttp访问封装
 * <p>
 * 1 支持没网缓存,和保质期
 * <p>
 * 2 支持强制读取缓存
 * <p>
 * 3 支持删除整个缓存和当个接口缓存
 * <p>
 * 4 支持大文件下载
 * <p>
 * 5 支持单个接口配置缓存,保质期,连接时间
 * <p>
 * 6 支持gzip压缩
 * <p>
 * 7 支持分批读取json数组,不会oom
 * 
 * @version 2017年2月21日
 * 
 */
public class OkHttpUtil {

	// 官方格式,文件为内容
	private static final String FILE_FLAG_CONTENT = ".1";
	// 官方格式,文件为响应头
	private static final String FILE_FLAG_HTTPHEAD = ".0";
	// 文件缓存的名字
	private static final String CACHE_NAME = "http_cache";

	private static final OkHttpClient mOkHttpClient;
	private static final okhttp3.OkHttpClient.Builder clientBuilder;
	private static final Context context = GlobalApplication.mContext;

	// 文件缓存
	private static final Cache cache;

	static {
		clientBuilder = new OkHttpClient.Builder();
		clientBuilder.connectTimeout(14, TimeUnit.SECONDS);// 设置连接超时12秒
		clientBuilder.writeTimeout(30, TimeUnit.SECONDS);
		clientBuilder.readTimeout(30, TimeUnit.SECONDS);
		int cachesize = 10 * 1024 * 100;
		File dir = context.getDir(CACHE_NAME, Context.MODE_PRIVATE);
		cache = new Cache(dir, cachesize);
		clientBuilder.cache(cache);
		clientBuilder.interceptors().add(new CacheApplicationInterceptor());
		// clientBuilder.addNetworkInterceptor(new GzipRequestInterceptor());
		mOkHttpClient = clientBuilder.build();
	}

	public static String get(String url, Map<String, String> parmter, HashMap<String, Object> config)
			throws IOException {
		String content = "";
		Set<String> keySet = parmter.keySet();
		int i = 0;
		String start = null;

		if (url.contains("?"))
			start = "&";
		else
			start = "?";

		for (String key : keySet) {
			if (i == 0)
				content = content + key + "=" + parmter.get(key);
			else
				content = content + "&" + key + "=" + parmter.get(key);
			i++;
		}

		url = url + start + content;
		return get(url, config);
	}

	public static String get(String url, HashMap<String, Object> config) throws IOException {
		okhttp3.Request.Builder build = creatBuilder();
		Request request = build.url(url).build();
		build.tag(config);
		OkHttpClient copyClient = connectionParmter(config, mOkHttpClient);
		Response response = execute(copyClient, request);

		if (response.isSuccessful())
			return response.body().string();

		return null;
	}

	// 分批加载json数据
	public static void getBigJsonData(String url, ObserverBigCallBack back, int method, Object obj) {
		BigJsonThread bigJsonThread = new BigJsonThread(url, back, method, obj);
		new Thread(bigJsonThread).start();
	}

	// 堵塞的post请求
	private static String postString(String url, Map<String, Object> body, HashMap<String, Object> config) {
		Builder type = new FormBody.Builder();
		Set<String> keySet = body.keySet();
		for (String key : keySet)
			type.add(key, (String) body.get(key));
		RequestBody requestBody = type.build();
		okhttp3.Request.Builder builder = creatBuilder();
		builder.tag(config);
		OkHttpClient copyClient = connectionParmter(config, mOkHttpClient);
		// "Connection", "close"这个解决报错 不让他长连接
		Request request = builder.url(url).post(requestBody).addHeader("Connection", "close").build();
		Response execute;
		try {
			execute = execute(copyClient, request);
			keySet = null;
			if (execute.isSuccessful())
				return execute.body().string();

		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String post(String url, Map<String, Object> body, HashMap<String, Object> config) {
		Set<String> keySet = body.keySet();
		boolean isHasFile = false;
		for (String value : keySet) {
			Object object = body.get(value);
			if (object instanceof File) {
				isHasFile = true;
				break;
			}
		}

		if (!isHasFile)
			return postString(url, body, config);

		okhttp3.Request.Builder build = creatBuilder();
		build.tag(config);
		OkHttpClient copyClient = connectionParmter(config, mOkHttpClient);
		// 构造上传请求,类似web表单
		okhttp3.MultipartBody.Builder type = new MultipartBody.Builder();

		RequestBody fileBody = null;
		keySet = body.keySet();
		for (String key : keySet) {
			Object object = body.get(key);
			if (object == null)
				continue;

			if (object instanceof String) {
				type.addFormDataPart(key, (String) object);
				Headers of = Headers.of("Content-Disposition", "form-data; name=\"" + key + "\"");
				type.addPart(of, RequestBody.create(null, (String) object));
			} else if (object instanceof File) {
				File file = (File) object;
				fileBody = RequestBody.create(MediaType.parse(guessMimeType(file.getName())), file);
				String format = "form-data; name=\"" + key + "\"; filename=\"" + file.getName() + "\"\r\n";
				Headers of = Headers.of("Content-Disposition", format);
				type.addPart(of, fileBody);
			}
		}

		RequestBody requestBody = type.build();
		Request request = build.url(url).post(requestBody).build();
		try {
			Response execute = execute(copyClient, request);
			boolean successful = execute.isSuccessful();
			if (successful)
				return execute.body().string();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void download(String url, File file, ObserverCallBack back, int method, Object obj,
			HashMap<String, Object> config) {
		okhttp3.Request.Builder build = creatBuilder();
		build.tag(config);
		OkHttpClient copyClient = connectionParmter(config, mOkHttpClient);
		Request request = build.url(url).build();
		FileOkCallBack fileOkCallBack = new FileOkCallBack(file, back, method, obj);
		enqueue(copyClient, request, fileOkCallBack);
	}

	// 结束所有网络请求
	public static void cancelAll() {
		mOkHttpClient.dispatcher().cancelAll();
	}

	public static void get(String url, ObserverCallBack back, int method, Object obj, HashMap<String, Object> config) {
		OkCallBack okCallBack = new OkCallBack(back, method, obj);
		Request.Builder build = creatBuilder();
		build.tag(config);
		OkHttpClient copyClient = connectionParmter(config, mOkHttpClient);
		Request request = build.url(url).build();
		enqueue(copyClient, request, okCallBack);
	}

	public static void postFile(String url, File file, ObserverCallBack back, int method, Object obj,
			HashMap<String, Object> config) {
		RequestBody create = RequestBody.create(MediaType.parse(guessMimeType(file.getName())), file);
		okhttp3.Request.Builder build = creatBuilder();
		build.tag(config);
		OkHttpClient copyClient = connectionParmter(config, mOkHttpClient);
		Request request = build.url(url).post(create).build();
		OkCallBack okCallBack = new OkCallBack(back, method, obj);
		enqueue(copyClient, request, okCallBack);
	}

	public static void post(String url, Map<String, Object> body, ObserverCallBack back, int method, Object obj,
			HashMap<String, Object> config) {
		Set<String> keySet = body.keySet();
		boolean isHasFile = false;
		for (String value : keySet) {
			Object object = body.get(value);
			if (object instanceof File) {
				isHasFile = true;
				break;
			}
		}

		if (!isHasFile) {
			postString(url, body, back, method, obj, config);
			return;
		}

		okhttp3.Request.Builder build = creatBuilder();
		build.tag(config);
		OkHttpClient copyOkHttpClient = connectionParmter(config, mOkHttpClient);

		// 构造上传请求,类似web表单
		okhttp3.MultipartBody.Builder type = new MultipartBody.Builder();
		keySet = body.keySet();
		RequestBody fileBody = null;

		for (String key : keySet) {
			Object object = body.get(key);
			if (object == null)
				continue;

			if (object instanceof String) {
				type.addFormDataPart(key, (String) object);
			} else if (object instanceof File) {
				File file = (File) object;
				fileBody = RequestBody.create(MediaType.parse(guessMimeType(file.getName())), file);
				String format = "form-data; name=\"" + key + "\"; filename=\"" + file.getName() + "\"\r\n";
				type.addPart(Headers.of("Content-Disposition", format), fileBody);
			}
		}

		RequestBody requestBody = type.build();
		Request request = build.url(url).post(requestBody).build();
		OkCallBack okCallBack = new OkCallBack(back, method, obj);
		enqueue(copyOkHttpClient, request, okCallBack);
	}

	private static void postString(String url, Map<String, Object> body, ObserverCallBack back, int method, Object obj,
			HashMap<String, Object> config) {
		Builder type = new FormBody.Builder();
		Set<String> keySet = body.keySet();

		for (String key : keySet)
			type.add(key, (String) body.get(key));

		RequestBody requestBody = type.build();
		okhttp3.Request.Builder builder = creatBuilder();
		builder.tag(config);
		OkHttpClient copyClient = connectionParmter(config, mOkHttpClient);
		Request request = builder.url(url).post(requestBody).build();
		OkCallBack okCallBack = new OkCallBack(back, method, obj);
		enqueue(copyClient, request, okCallBack);
	}

	// ----------------------------------------

	public static Response execute(Request request) throws IOException {
		return mOkHttpClient.newCall(request).execute();
	}

	private static Response execute(OkHttpClient mOkHttpClient, Request request) throws IOException {
		return mOkHttpClient.newCall(request).execute();
	}

	/**
	 * 开启异步线程访问网络
	 * 
	 * @param request
	 * @param responseCallback
	 */
	private static void enqueue(OkHttpClient mOkHttpClient, Request request, Callback responseCallback) {
		mOkHttpClient.newCall(request).enqueue(responseCallback);
	}

	// 配置连接参数
	private static OkHttpClient connectionParmter(HashMap<String, Object> config, OkHttpClient copyClient) {
		long connectionTime = HttpConfig.getConnectionTime(config);
		long readTime = HttpConfig.getReadTime(config);

		if (connectionTime > 0 || readTime > 0) {

			long currConnectTimeout = TimeUnit.MILLISECONDS.toSeconds(mOkHttpClient.connectTimeoutMillis());
			long currReadTime = TimeUnit.MILLISECONDS.toSeconds(mOkHttpClient.readTimeoutMillis());

			if (connectionTime < 1)
				connectionTime = currConnectTimeout;

			if (readTime < 1)
				readTime = currReadTime;

			// Copy to customize OkHttp for this request.
			copyClient = mOkHttpClient.newBuilder().connectTimeout(connectionTime, TimeUnit.SECONDS)
					.writeTimeout(mOkHttpClient.writeTimeoutMillis(), TimeUnit.SECONDS)
					.readTimeout(readTime, TimeUnit.SECONDS).build();

		}
		return copyClient;
	}

	private static Request.Builder creatBuilder() {
		okhttp3.Request.Builder build = new Request.Builder();
		return build;
	}

	// 按照okhttp删除对应的缓存
	public static void clearCache(String url) {
		okhttp3.Request.Builder builder = creatBuilder();
		Request request = builder.url(url).build();

		String md5Hex = Util.md5Hex(request.url().toString());

		if (cache == null)
			return;

		File directory = cache.directory();
		File fileContent = new File(directory, md5Hex + FILE_FLAG_CONTENT);
		File fileHead = new File(directory, md5Hex + FILE_FLAG_HTTPHEAD);

		if (fileContent != null)
			FileUtil.delete(fileContent);

		if (fileHead != null)
			FileUtil.delete(fileHead);
	}

	// 清除缓存.0的文件是header .1的文件是数据
	public static void clearCache() {
		if (cache == null)
			return;

		File directory = cache.directory();

		if (directory != null)
			FileUtil.delete(directory);
	}

	private static String guessMimeType(String path) {
		FileNameMap fileNameMap = URLConnection.getFileNameMap();
		String contentTypeFor = fileNameMap.getContentTypeFor(path);
		if (contentTypeFor == null) {
			contentTypeFor = "application/octet-stream";
		}
		return contentTypeFor;
	}

	/**
	 * 从磁盘读取网络缓存,不支持gzip
	 * 
	 * @param request
	 * @return
	 */
	private static Response getCacheResponse(Request request) {
		Class<? extends Cache> class1 = cache.getClass();
		Method method = null;
		try {
			method = class1.getDeclaredMethod("get", Request.class);
		} catch (Exception e) {
			e.printStackTrace();
		}

		method.setAccessible(true);
		Response res = null;
		try {
			res = (Response) method.invoke(cache, request);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return res;
	}

	// 从磁盘读取缓存
	public static String getCacheResponse(String url) {
		if (cache == null)
			return null;

		okhttp3.Request.Builder builder = creatBuilder();
		Request request = builder.url(url).build();
		String key = Util.md5Hex(request.url().toString());
		File directory = cache.directory();
		File fileContent = new File(directory, key + FILE_FLAG_CONTENT);
		File fileHead = new File(directory, key + FILE_FLAG_HTTPHEAD);

		if (fileContent != null && fileContent.exists()) {
			Response response = getCacheResponse(request, fileContent, fileHead);
			if (response == null)
				return null;

			try {
				return response.body().string();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return null;
	}

	// 从磁盘读取网络缓存,并且支持gzip
	private static Response getCacheResponse(Request request, File fileContent, File fileHead) {
		boolean isGzip = isGzip(fileHead);
		okhttp3.Response.Builder builder = new Response.Builder();
		builder.body(new FileResponseBody(fileContent, isGzip));
		builder.request(request);
		builder.code(200);
		builder.protocol(Protocol.HTTP_1_1);
		Response res = builder.build();
		return res;
	}

	private static boolean isGzip(File fileHead) {
		boolean isGzip = false;

		if (fileHead == null)
			return isGzip;

		FileReader fr = null;
		BufferedReader br = null;
		try {
			fr = new FileReader(fileHead);
			br = new BufferedReader(fr);
			String line = null;
			// 官方存储的格式
			String GZIP = "Content-Encoding: gzip";
			while ((line = br.readLine()) != null) {
				if (TextUtils.equals(line, GZIP)) {
					isGzip = true;
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭缓冲读入流及文件读入流的连接.
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return isGzip;
	}

	// 实现缓存功能
	static class CacheApplicationInterceptor implements Interceptor {

		@Override
		public Response intercept(Chain chain) throws IOException {
			Request request = chain.request();

			HashMap<String, Object> config = HttpConfig.getConfig(request.tag());
			int maxAge = -1;
			int maxStale = -1;

			File fileContent = null;
			File fileHead = null;

			if (config != null) {
				maxAge = HttpConfig.getMaxAge(config);
				maxStale = HttpConfig.getMaxStale(config);
			}

			// 处理存活期
			if (maxAge > 0) {
				String md5Hex = Util.md5Hex(request.url().toString());
				File directory = cache.directory();
				fileContent = new File(directory, md5Hex + FILE_FLAG_CONTENT);
				fileHead = new File(directory, md5Hex + FILE_FLAG_HTTPHEAD);

				boolean isUse = false;

				if (fileContent != null && fileContent.exists()) {
					long lastModified = fileContent.lastModified();
					long currentThreadTimeMillis = System.currentTimeMillis();
					isUse = currentThreadTimeMillis - lastModified < maxAge * 1000;
				}

				Response cacheResponse = null;
				if (isUse)
					cacheResponse = getCacheResponse(request, fileContent, fileHead);

				if (cacheResponse != null) {
					LogUtil.i("--okhttp--", "数据来自缓存(存活期)");
					return cacheResponse;
				}
			}

			// 处理没网缓存
			if (!hasConnectedNetwork(context) && maxStale > 0) {
				if (fileContent == null) {
					String md5Hex = Util.md5Hex(request.url().toString());
					File directory = cache.directory();
					fileContent = new File(directory, md5Hex + FILE_FLAG_CONTENT);
					fileHead = new File(directory, md5Hex + FILE_FLAG_HTTPHEAD);
				}

				boolean isUse = false;

				if (fileContent != null && fileContent.exists()) {
					long lastModified = fileContent.lastModified();
					long currentThreadTimeMillis = System.currentTimeMillis();
					isUse = currentThreadTimeMillis - lastModified < maxStale * 1000;
				}

				Response cacheResponse = null;
				if (isUse)
					cacheResponse = getCacheResponse(request, fileContent, fileHead);

				if (cacheResponse != null) {
					LogUtil.i("--okhttp--", "数据来自缓存");
					return cacheResponse;
				}
			}

			return chain.proceed(request);
		}

		public static boolean hasConnectedNetwork(Context context) {
			ConnectivityManager connectivity = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);

			if (connectivity == null)
				return false;

			NetworkInfo[] info = connectivity.getAllNetworkInfo();

			if (info == null)
				return false;

			for (int i = 0; i < info.length; i++) {
				if (info[i].getState() == NetworkInfo.State.CONNECTED) {
					info = null;
					return true;
				}
			}
			return false;
		}
	}

	/** 可以选择不用开启 */
	static class GzipRequestInterceptor implements Interceptor {

		@Override
		public Response intercept(Chain chain) throws IOException {
			Request originalRequest = chain.request();
			if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
				return chain.proceed(originalRequest);
			}

			Request compressedRequest = originalRequest.newBuilder().header("Content-Encoding", "gzip")
					.method(originalRequest.method(), gzip(originalRequest.body())).build();
			return chain.proceed(compressedRequest);
		}

		private RequestBody gzip(final RequestBody body) {
			return new RequestBody() {

				@Override
				public MediaType contentType() {
					return body.contentType();
				}

				@Override
				public long contentLength() {
					return -1; // 无法知道压缩后的数据大小
				}

				@Override
				public void writeTo(BufferedSink sink) throws IOException {
					BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
					body.writeTo(gzipSink);
					gzipSink.close();
				}
			};
		}
	}

}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.os.Handler;
import android.os.Looper;
import okhttp3.Request;
import okhttp3.Response;

class BigJsonThread implements Runnable {

	private static Handler handler = new Handler(Looper.getMainLooper());

	private String url;
	private ObserverBigCallBack back;
	private int method;
	private Object obj;

	public BigJsonThread(String url, ObserverBigCallBack back, int method, Object obj) {
		this.url = url;
		this.back = back;
		this.method = method;
		this.obj = obj;
	}

	// 在子线程中调主线程的回调方法
	private void postHandlerBigData(final ObserverBigCallBack back, final String methodFunction, final String response,
			final int method, final Object obj) {

		handler.post(new Runnable() {

			public void run() {
				switch (methodFunction) {
				case "badBack":
					back.badBack(null, method, obj);
					break;
				case "startBack":
					back.startBack(method, obj);
					break;
				case "endBack":
					back.endBack(method, obj);
					break;
				case "finallyBack":
					back.finallyBack(method, obj);
					break;
				}
			}
		});
	}

	@Override
	public void run() {
		Request request = new Request.Builder().url(url).build();

		BufferedReader read = null;
		InputStream byteStream = null;
		try {
			Response execute = OkHttpUtil.execute(request);

			if (execute != null && !execute.isSuccessful()) {
				postHandlerBigData(back, "badBack", null, method, obj);
				return;
			}

			byteStream = execute.body().byteStream();
			StringBuilder old = new StringBuilder();
			read = new BufferedReader(new InputStreamReader(byteStream));// 防止中文乱码
			char[] buffer = new char[2048];
			int len = -1;
			boolean init = true;
			while ((len = read.read(buffer)) != -1) {// 分段加载
				if (init) {
					init = false;
					postHandlerBigData(back, "startBack", null, method, obj);
				}
				old.append(buffer, 0, len);
				int indexOfStart = -1;
				int indexOfEnd = -1;
				while (old != null && old.length() > 1 && (indexOfStart = old.indexOf("{")) >= 0
						&& (indexOfEnd = old.indexOf("}", indexOfStart)) >= 0 && indexOfStart < indexOfEnd) {

					String item = old.substring(indexOfStart, indexOfEnd + 1);
					if (item != null)
						back.back(item, method, null);
					item = null;
					old.delete(0, indexOfEnd + 1);
				}
			}
			buffer = null;
			old = null;
			postHandlerBigData(back, "endBack", null, method, obj);
		} catch (IOException e1) {
			postHandlerBigData(back, "badBack", null, method, obj);
		} finally {
			try {
				if (read != null)
					read.close();
				if (byteStream != null)
					byteStream.close();
				byteStream = null;
				read = null;
			} catch (IOException e) {
			}
			postHandlerBigData(back, "finallyBack", null, method, obj);
		}
	}
}

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.Call;
import okhttp3.Response;

public class FileOkCallBack extends OkCallBack {
	protected File file;

	public FileOkCallBack(File address, ObserverCallBack back, int mehtod, Object obj) {
		super(back, mehtod, obj);
		this.file = address;
	}

	@Override
	public void onResponse(Call arg1, Response response){
		
		InputStream is = null;
		byte[] buf = new byte[2048];
		int len = 0;
		FileOutputStream fos = null;
		try {
			is = response.body().byteStream();
			fos = new FileOutputStream(file);
			while ((len = is.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}
			fos.flush();
			// 如果下载文件成功,第一个参数为文件的绝对路径
			handler.post(new Runnable() {
				public void run() {
					if (back != null) {
						back.back(file.getAbsolutePath(), method, obj);
					}
				}
			});
		} catch (IOException e) {
			LogUtil.e(e);
			handler.post(new Runnable() {
				public void run() {
					if (back != null) {
						back.badBack(file.getAbsolutePath(), method, obj);
					}
				}
			});
		} finally {
			try {
				if (is != null)
					is.close();
			} catch (IOException e) {
			}
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
			}
		}

	}
}

import java.io.File;

import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.BufferedSource;
import okio.Okio;

/**
 * 读取缓存文件的内容
 * <p>
 *
 * @version 2017年2月21日
 */
public class FileResponseBody extends ResponseBody {
	private FileSource fileSource;

	public FileResponseBody(File file, boolean isGzip) {
		fileSource = new FileSource(file, isGzip);
	}

	@Override
	public BufferedSource source() {
		return Okio.buffer(fileSource);
	}

	@Override
	public MediaType contentType() {
		return null;
	}

	@Override
	public long contentLength() {
		return -1;
	}
}


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import okio.Buffer;
import okio.Source;
import okio.Timeout;

/**
 * 读取文件源
 * <p>
 *
 * @version 2017年2月21日
 */
public class FileSource implements Source {

	private File file = null;
	private FileInputStream fileInputStream;
	private boolean isGzip;
	private InputStream inputStream;
	private int contentLength = 0;

	public FileSource(File file, boolean isGzip) {
		this.file = file;
		this.isGzip = isGzip;
	}

	public long contentLength() {
		return contentLength;
	}

	@Override
	public void close() throws IOException {
		if (fileInputStream != null) {
			fileInputStream.close();
			fileInputStream = null;
		}

		if (inputStream != null) {
			inputStream.close();
			inputStream = null;
		}
	}

	// res.body().string()调用会执行read
	@Override
	public long read(Buffer arg0, long arg1) throws IOException {

		if (fileInputStream == null) {
			fileInputStream = new FileInputStream(file);

			if (isGzip)
				inputStream = GzipUtil.convertGzipStream(fileInputStream);
			else
				inputStream = fileInputStream;
		}

		byte[] data = new byte[1024];
		int read = inputStream.read(data);
		if (read >= 0)
			arg0.write(data, 0, read);

		if (read != -1) {
			contentLength += read;
		}

		data = null;
		return read;
	}

	@Override
	public Timeout timeout() {
		return null;
	}

}


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GzipUtil {
	
	// 压缩
	public static String compress(String str) throws IOException {
		if (str == null || str.length() == 0) {
			return str;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		GZIPOutputStream gzip = new GZIPOutputStream(out);
		gzip.write(str.getBytes());
		gzip.close();
		out.close();
		return out.toString();
	}

	// 解压缩
	public static String uncompress(String str) throws IOException {
		if (str == null || str.length() == 0) {
			return str;
		}
		ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes());
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		GZIPInputStream gunzip = new GZIPInputStream(in);
		byte[] buffer = new byte[256];
		int n;
		while ((n = gunzip.read(buffer)) >= 0) {
			out.write(buffer, 0, n);
		}
		in.close();
		out.close();
		gunzip.close();
		// toString()使用平台默认编码,也可以显式的指定如toString("GBK")
		return out.toString();
	}

	// 解压缩
	public static GZIPInputStream convertGzipStream(InputStream str) throws IOException {
		if (str == null) {
			return null;
		}
		GZIPInputStream gunzip = new GZIPInputStream(str);
		return gunzip;
	}

}

import java.util.HashMap;

/**
 * 网络配置类
 * 
 *
 *   2017年2月21日
 */
public class HttpConfig {
	public static final String CONNECT_TIME = "con-time";// 可连接时间,单位秒
	public static final String READ_TIME_OUT = "read-time";// 可读时间,单位秒
	public static final String MAX_AGE = "max-age";// 存活时间,多少秒之内不用走网络,单位秒
	public static final String MAX_STALE = "max-stale";// 没获取成功走本地的网络缓存,单位秒

	public static boolean isForceCache(HashMap<String, Object> map) {
		if (map == null)
			return false;

		boolean containsKey = map.containsKey(CONNECT_TIME);
		if (containsKey) {
			Object object = map.get(CONNECT_TIME);
			if (object != null && object instanceof Boolean)
				return (Boolean) object;
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	public static HashMap<String, Object> getConfig(Object obj) {
		if (obj == null)
			return null;

		if (obj instanceof HashMap)
			return (HashMap<String, Object>) obj;

		return null;
	}

	public static int getConnectionTime(HashMap<String, Object> map) {
		if (map == null)
			return -1;

		boolean containsKey = map.containsKey(CONNECT_TIME);
		if (containsKey) {
			Object object = map.get(CONNECT_TIME);
			if (object != null && object instanceof Integer)
				return (int) object;
		}
		return -1;
	}

	public static int getReadTime(HashMap<String, Object> map) {
		if (map == null)
			return -1;
		boolean containsKey = map.containsKey(READ_TIME_OUT);
		if (containsKey) {
			Object object = map.get(READ_TIME_OUT);
			if (object != null && object instanceof Integer)
				return (int) object;
		}
		return -1;
	}

	public static int getMaxAge(HashMap<String, Object> map) {
		if (map == null)
			return -1;

		boolean containsKey = map.containsKey(MAX_AGE);
		if (containsKey) {
			Object object = map.get(MAX_AGE);
			if (object != null && object instanceof Integer)
				return (int) object;
		}
		return -1;
	}

	public static int getMaxStale(HashMap<String, Object> map) {
		if (map == null)
			return -1;

		boolean containsKey = map.containsKey(MAX_STALE);
		if (containsKey) {
			Object object = map.get(MAX_STALE);
			if (object != null && object instanceof Integer)
				return (int) object;
		}
		return -1;
	}

	public static HashMap<String, Object> newConfig() {
		HashMap<String, Object> config = new HashMap<String, Object>();
		return config;
	}

	public static HashMap<String, Object> newConfig(int maxAge, int maxStale) {
		HashMap<String, Object> config = new HashMap<String, Object>();
		config.put(MAX_AGE, maxAge);
		config.put(MAX_STALE, maxStale);
		return config;
	}

	public static HashMap<String, Object> defaultConfig() {
		// 存活2分钟,缓存2天
		return newConfig(120, 60 * 60 * 24 * 2);
	}

	public static HashMap<String, Object> smallConfig() {
		// 存活1小时,缓存2天
		return newConfig(60 * 60, 60 * 60 * 24 * 2);
	}

	public static HashMap<String, Object> middleConfig() {
		// 存活24小时,缓存5天
		return newConfig(60 * 60 * 24, 60 * 60 * 24 * 5);
	}

}


/**
 * 分批返回
 * <p>
 *
 * @version 2016年4月20日
 */
public interface ObserverBigCallBack extends ObserverCallBack {
	
	public void startBack(int method, Object obj);

	public void endBack(int method, Object obj);
	
	public void finallyBack(int method, Object obj);

}

public interface ObserverCallBack {
	/**
	 * 
	 * @param data
	 *            服务端的信息
	 * @param encoding
	 *            响应状态
	 * @param method
	 *            请求的接口
	 * @param obj
	 *            附带值
	 */
	public void back(String data, int method, Object obj);

	public void badBack(String error, int method, Object obj);
}


import java.io.IOException;
import java.net.URL;


import android.os.Handler;
import android.os.Looper;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Response;

public class OkCallBack implements Callback {

	protected static Handler handler = new Handler(Looper.getMainLooper());

	protected ObserverCallBack back;
	protected int method;
	protected Object obj;
	protected String response;

	public OkCallBack(ObserverCallBack back, int method, Object obj) {
		this.back = back;
		this.method = method;
		this.obj = obj;
	}

	@Override
	public void onFailure(Call arg0, IOException arg1) {
		if (arg1 != null && arg0 != null) //需要try catch
			response = arg1.toString();
			
		failed();
	}

	@Override
	public void onResponse(Call arg1, Response arg0)  {
		if (arg0 != null) //需要try catch 
			response = arg0.body().string();
		
		successful();
	}

	private void successful() {
		if (back == null)
			return;
		handler.post(new Runnable() {

			public void run() {
				back.back(response, method, obj);
			}
		});
	}

	private void failed() {
		if (back == null)
			return;
		handler.post(new Runnable() {

			public void run() {
				back.badBack(response, method, obj);
			}
		});
	}

}

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.os.Environment;

public class FileUtil {

	/**
	 * 删除文件(包括子文件)
	 * 
	 * @param file
	 */
	public static void delete(File file) {
		if (file.isDirectory()) {
			File[] childs = file.listFiles();
			for (File file2 : childs)
				delete(file2);
		}
		file.delete();
	}

}



//如果版本是大于3.4.1,的可能找不到Util.md5Hex()方法,源码里面Util.md5Hex变成了Cache.key,如下

// okhttp
public static String md5Hex(HttpUrl url) { 
	return Cache.key(url);
}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值