android 简单封装okhttp3工具类

public class OkHttp3Utils {

	private volatile static OkHttp3Utils mInstance;

	private OkHttpClient mOkHttpClient;

	private Handler mHandler;

	private Context mContext;

	private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

	private OkHttp3Utils(Context context) {
		super();
		Builder clientBuilder = new OkHttpClient().newBuilder();
		clientBuilder.readTimeout(30, TimeUnit.SECONDS);
		clientBuilder.connectTimeout(15, TimeUnit.SECONDS);
		clientBuilder.writeTimeout(60, TimeUnit.SECONDS);
		mOkHttpClient = clientBuilder.build();
		this.mContext = context.getApplicationContext();
		mHandler = new Handler(mContext.getMainLooper());
	}

	public static OkHttp3Utils getInstance(Context context) {
		OkHttp3Utils temp = mInstance;
		if (temp == null) {
			synchronized (OkHttp3Utils.class) {
				temp = mInstance;
				if (temp == null) {
					temp = new OkHttp3Utils(context);
					mInstance = temp;
				}
			}
		}
		return temp;
	}

	/**
	 * 设置请求头
	 * 
	 * @param headersParams
	 * @return
	 */
	private Headers SetHeaders(Map<String, String> headersParams) {
		Headers headers = null;
		Headers.Builder headersbuilder = new Headers.Builder();
		if (headersParams != null) {
			Iterator<String> iterator = headersParams.keySet().iterator();
			String key = "";
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				headersbuilder.add(key, headersParams.get(key));
			}
		}
		headers = headersbuilder.build();
		return headers;
	}

	/**
	 * post请求参数
	 * 
	 * @param BodyParams
	 * @return
	 */
	private RequestBody SetPostRequestBody(Map<String, String> BodyParams) {
		RequestBody body = null;
		FormBody.Builder formEncodingBuilder = new FormBody.Builder();
		if (BodyParams != null) {
			Iterator<String> iterator = BodyParams.keySet().iterator();
			String key = "";
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				formEncodingBuilder.add(key, BodyParams.get(key));
			}
		}
		body = formEncodingBuilder.build();
		return body;
	}

	/**
	 * Post上传图片的参数
	 * 
	 * @param BodyParams
	 * @param fileParams
	 * @return
	 */
	private RequestBody SetFileRequestBody(Map<String, String> BodyParams, Map<String, String> filePathParams) {
		// 带文件的Post参数
		RequestBody body = null;
		MultipartBody.Builder MultipartBodyBuilder = new MultipartBody.Builder();
		MultipartBodyBuilder.setType(MultipartBody.FORM);
		RequestBody fileBody = null;
		if (BodyParams != null) {
			Iterator<String> iterator = BodyParams.keySet().iterator();
			String key = "";
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				MultipartBodyBuilder.addFormDataPart(key, BodyParams.get(key));
			}
		}
		if (filePathParams != null) {
			Iterator<String> iterator = filePathParams.keySet().iterator();
			String key = "";
			int i = 0;
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				i++;
				MultipartBodyBuilder.addFormDataPart(key, filePathParams.get(key));
				fileBody = RequestBody.create(MEDIA_TYPE_PNG, new File(filePathParams.get(key)));
				MultipartBodyBuilder.addFormDataPart(key, i + ".png", fileBody);
			}
		}
		body = MultipartBodyBuilder.build();
		return body;
	}

	/**
	 * get方法连接拼加参数
	 * 
	 * @param mapParams
	 * @return
	 */
	private String setGetUrlParams(Map<String, String> mapParams) {
		String strParams = "";
		if (mapParams != null) {
			Iterator<String> iterator = mapParams.keySet().iterator();
			String key = "";
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				strParams += "&" + key + "=" + mapParams.get(key);
			}
		}
		return strParams;
	}

	/**
	 * 实现post请求
	 * 
	 * @param reqUrl
	 * @param headersParams
	 * @param params
	 * @param callback
	 */
	public void doPost(String reqUrl, Map<String, String> headersParams, Map<String, String> params, final NetCallback callback) {
		Request.Builder RequestBuilder = new Request.Builder();
		RequestBuilder.url(reqUrl);// 添加URL地址
		RequestBuilder.method("POST", SetPostRequestBody(params));
		RequestBuilder.headers(SetHeaders(headersParams));// 添加请求头
		Request request = RequestBuilder.build();
		mOkHttpClient.newCall(request).enqueue(new Callback() {

			@Override
			public void onResponse(final Call call, final Response response) throws IOException {
				mHandler.post(new Runnable() {

					@Override
					public void run() {
						callback.onSuccess(0, response.body().toString());
						call.cancel();
					}
				});
			}

			@Override
			public void onFailure(final Call call, final IOException exception) {
				mHandler.post(new Runnable() {

					@Override
					public void run() {
						callback.onFailure(-1, exception.getMessage());
						call.cancel();
					}
				});
			}
		});
	}

	/**
	 * 实现get请求
	 * 
	 * @param reqUrl
	 * @param headersParams
	 * @param params
	 * @param callback
	 */
	public void doGet(String reqUrl, Map<String, String> headersParams, Map<String, String> params, final NetCallback callback) {
		Request.Builder RequestBuilder = new Request.Builder();
		RequestBuilder.url(reqUrl + setGetUrlParams(params));// 添加URL地址 自行加 ?
		RequestBuilder.headers(SetHeaders(headersParams));// 添加请求头
		Request request = RequestBuilder.build();
		mOkHttpClient.newCall(request).enqueue(new Callback() {

			@Override
			public void onResponse(final Call call, final Response response) throws IOException {
				mHandler.post(new Runnable() {

					@Override
					public void run() {
						callback.onSuccess(0, response.body().toString());
						call.cancel();
					}
				});
			}

			@Override
			public void onFailure(final Call call, final IOException exception) {
				mHandler.post(new Runnable() {

					@Override
					public void run() {
						callback.onFailure(-1, exception.getMessage());
						call.cancel();
					}
				});
			}
		});
	}

	/**
	 * 实现加载图片
	 * 
	 * @param context
	 * @param reqUrl
	 * @param headersParams
	 * @param imageView
	 * @param defResImag  imageView.setImageResource(context.getResources().getIdentifier(defResImag, "drawable", context.getPackageName()));
	 */
	public void loadImage(final Context context, final String reqUrl, Map<String, String> headersParams, final ImageView imageView, final String defResImag) {
		Bitmap result;
		// 从内存缓存中获取图片
		final ImageMemoryCache memoryCache = new ImageMemoryCache(context);
		result = memoryCache.getBitmapFromCache(reqUrl);
		if (result != null) {
			imageView.setImageBitmap(result);
			return;
		}
		// 从硬盘缓存中获取图片
		final ImageFileCache fileCache = new ImageFileCache(context);
		result = fileCache.getImage(context, reqUrl);
		if (result != null) {
			imageView.setImageBitmap(result);
			// 添加到内存缓存
			memoryCache.addBitmapToCache(reqUrl, result);
			return;
		}
		Request.Builder RequestBuilder = new Request.Builder();
		RequestBuilder.url(reqUrl);// 添加URL地址
		// RequestBuilder.headers(SetHeaders(headersParams));// 添加请求头
		Request request = RequestBuilder.build();
		mOkHttpClient.newCall(request).enqueue(new Callback() {

			@Override
			public void onResponse(final Call call, final Response response) throws IOException {
				byte[] bytes = response.body().bytes();
				final Bitmap decodeStream = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
				mHandler.post(new Runnable() {

					@Override
					public void run() {
						try {
							if (decodeStream != null) {
								imageView.setImageBitmap(decodeStream);
								// 缓存在文件
								fileCache.saveBitmap(context, decodeStream, reqUrl);
								// 缓存在内存
								memoryCache.addBitmapToCache(reqUrl, decodeStream);
							} else {
								// 加载图片
								imageView.setImageResource(context.getResources().getIdentifier(defResImag, "drawable", context.getPackageName()));
							}
						} catch (Exception e) {
							e.printStackTrace();
						} finally {
							call.cancel();
						}
					}
				});
			}

			@Override
			public void onFailure(final Call call, final IOException exception) {
				mHandler.post(new Runnable() {

					@Override
					public void run() {
						// 加载图片
						imageView.setImageResource(context.getResources().getIdentifier(defResImag, "drawable", context.getPackageName()));
						call.cancel();
					}
				});
			}
		});
	}

	public abstract class NetCallback {
		public abstract void onFailure(int code, String msg);

		public abstract void onSuccess(int code, String content);

		public abstract void loadImage(Bitmap bitmap);
	}
}
public class ImageMemoryCache {
	/**
	 * 从内存读取数据速度是最快的,为了更大限度使用内存,这里使用了两层缓存。 硬引用缓存不会轻易被回收,用来保存常用数据,不常用的转入软引用缓存。
	 */
	private static final int SOFT_CACHE_SIZE = 15; // 软引用缓存容量
	private static LruCache<String, Bitmap> mLruCache; // 硬引用缓存
	private static LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache; // 软引用缓存

	public ImageMemoryCache(Context context) {
		int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
		int cacheSize = 1024 * 1024 * memClass / 4; // 硬引用缓存容量,为系统可用内存的1/4
		mLruCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap value) {
				if (value != null)
					return value.getRowBytes() * value.getHeight();
				else
					return 0;
			}

			@Override
			protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
				if (oldValue != null)
					// 硬引用缓存容量满的时候,会根据LRU算法把最近没有被使用的图片转入此软引用缓存
					mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));
			}
		};
		mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(SOFT_CACHE_SIZE, 0.75f, true) {
			private static final long serialVersionUID = 6040103833179403725L;

			@Override
			protected boolean removeEldestEntry(Entry<String, SoftReference<Bitmap>> eldest) {
				if (size() > SOFT_CACHE_SIZE) {
					return true;
				}
				return false;
			}
		};
	}

	/**
	 * 从缓存中获取图片
	 */
	public Bitmap getBitmapFromCache(String url) {
		Bitmap bitmap;
		// 先从硬引用缓存中获取
		synchronized (mLruCache) {
			bitmap = mLruCache.get(url);
			if (bitmap != null) {
				// 如果找到的话,把元素移到LinkedHashMap的最前面,从而保证在LRU算法中是最后被删除
				mLruCache.remove(url);
				mLruCache.put(url, bitmap);
				return bitmap;
			}
		}
		// 如果硬引用缓存中找不到,到软引用缓存中找
		synchronized (mSoftCache) {
			SoftReference<Bitmap> bitmapReference = mSoftCache.get(url);
			if (bitmapReference != null) {
				bitmap = bitmapReference.get();
				if (bitmap != null) {
					// 将图片移回硬缓存
					mLruCache.put(url, bitmap);
					mSoftCache.remove(url);
					return bitmap;
				} else {
					mSoftCache.remove(url);
				}
			}
		}
		return null;
	}

	/**
	 * 添加图片到缓存
	 */
	public void addBitmapToCache(String url, Bitmap bitmap) {
		if (bitmap != null) {
			synchronized (mLruCache) {
				mLruCache.put(url, bitmap);
			}
		}
	}

	public void clearCache() {
		mSoftCache.clear();
	}
}
public class ImageFileCache {
	private static final String CACHDIR = ".ImgCache";
	private static final String WHOLESALE_CONV = ".cache";

	private static final int MB = 1024 * 1024;
	private static final int CACHE_SIZE = 10;
	private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;

	public ImageFileCache(Context ctx) {
		// 清理文件缓存
		removeCache(ctx,getDirectory(ctx));
	}

	/** 从缓存中获取图片 **/
	public Bitmap getImage(Context ctx, final String url) {
		final String path = getDirectory(ctx) + "/" + convertUrlToFileName(url);
		File file = new File(path);
		if (file.exists()) {
			Bitmap bmp = BitmapFactory.decodeFile(path);
			if (bmp == null) {
				file.delete();
			} else {
				updateFileTime(path);
				return bmp;
			}
		}
		return null;
	}

	/** 将图片存入文件缓存 **/
	public void saveBitmap(Context ctx, Bitmap bm, String url) {
		if (bm == null) {
			return;
		}
		// 判断sdcard上的空间
		if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd(ctx)) {
			// SD空间不足
			return;
		}
		String filename = convertUrlToFileName(url);
		String dir = getDirectory(ctx);
		File dirFile = new File(dir);
		if (!dirFile.exists())
			dirFile.mkdirs();
		File file = new File(dir + "/" + filename);
		try {
			file.createNewFile();
			OutputStream outStream = new FileOutputStream(file);
			bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
			outStream.flush();
			outStream.close();
		} catch (FileNotFoundException e) {
			Log.w("ImageFileCache", "FileNotFoundException");
		} catch (IOException e) {
			Log.w("ImageFileCache", "IOException");
		}
	}

	/**
	 * 计算存储目录下的文件大小,
	 * 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
	 * 那么删除40%最近没有被使用的文件
	 */
	private boolean removeCache(Context ctx,String dirPath) {
		File dir = new File(dirPath);
		File[] files = dir.listFiles();
		if (files == null) {
			return true;
		}
//		if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
//			return false;
//		}
		int dirSize = 0;
		for (int i = 0; i < files.length; i++) {
			if (files[i].getName().contains(WHOLESALE_CONV)) {
				dirSize += files[i].length();
			}
		}
		if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd(ctx)) {
			int removeFactor = (int) ((0.4 * files.length) + 1);
			Arrays.sort(files, new FileLastModifSort());
			for (int i = 0; i < removeFactor; i++) {
				if (files[i].getName().contains(WHOLESALE_CONV)) {
					files[i].delete();
				}
			}
		}
		if (freeSpaceOnSd(ctx) <= CACHE_SIZE) {
			return false;
		}
		return true;
	}

	/** 修改文件的最后修改时间 **/
	public void updateFileTime(String path) {
		File file = new File(path);
		long newModifiedTime = System.currentTimeMillis();
		file.setLastModified(newModifiedTime);
	}

	/** 计算sdcard上的剩余空间 **/
	private int freeSpaceOnSd(Context ctx) {
		StatFs stat = new StatFs(getCachePath(ctx));
		double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;
		return (int) sdFreeMB;
	}

	/** 将url转成文件名 **/
	private String convertUrlToFileName(String url) {
		String[] strs = url.split("/");
		return strs[strs.length - 1] + WHOLESALE_CONV;
	}

	/** 获得缓存目录 **/
	private String getDirectory(Context ctx) {
		String dir = getCachePath(ctx);
		return dir;
	}

	/** 取SD卡路径 **/
	private String getSDPath() {
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
		if (sdCardExist) {
			sdDir = Environment.getExternalStorageDirectory(); // 获取根目录
		}
		if (sdDir != null) {
			return sdDir.toString();
		} else {
			return null;
		}
	}

	private String getCachePath(Context ctx) {
		String sdCardPath = getSDPath();
		if (sdCardPath != null) {
			return sdCardPath + File.separator + "Android" + File.separator + "data" + File.separator + ctx.getPackageName() + File.separator + CACHDIR;
		}
		return ctx.getFilesDir().getAbsolutePath() + File.separator + CACHDIR;
	}

	/**
	 * 根据文件的最后修改时间进行排序
	 */
	private class FileLastModifSort implements Comparator<File> {
		public int compare(File arg0, File arg1) {
			if (arg0.lastModified() > arg1.lastModified()) {
				return 1;
			} else if (arg0.lastModified() == arg1.lastModified()) {
				return 0;
			} else {
				return -1;
			}
		}
	}

}

 

转载于:https://my.oschina.net/moziqi/blog/733323

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值