1.三級緩存
package com.heima.zhbj55.view;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.heima.zhbj55.utils.MD5Utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.util.Log;
public class ImageCache {
private Context context;
private LruCache<String, Bitmap> lruCache;
private ExecutorService newFixedThreadPool;
private Handler handler;
public static final int SUCCESS = 10;
public static final int FAIL = 20;
private static final String tag = "ImageCache";
//handler對象是由使用者傳入過來的,說明處理資料的方法在使用者那邊
public ImageCache(Context context,Handler handler) {
this.context = context;
// 擷取最大記憶體的1/8作為lru最大可使用的記憶體
int cacSize = (int) (Runtime.getRuntime().maxMemory() / 8);
// 原理:
// 如果現在添加某一張圖檔,加上原有已使用記憶體大小以後大于cacSize大小,會自動移除最近最少使用的圖檔,保證記憶體大小不超過cacSize
lruCache = new LruCache<String, Bitmap>(cacSize) {
// 想删除某一張圖檔,前提必須知道圖檔的大小
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
};
this.handler = handler;
// 建立一個線程池,線程池中可開啟的線程數量(cpu個數*2+1)這是最佳數量的個數
newFixedThreadPool = Executors.newFixedThreadPool(5);
}
/**
* 解析指定位址的圖檔并且三級緩存圖檔
* @param url 圖檔位址
* @param position 圖檔的标示,為了擷取到每一張圖檔所用
* @return 傳回Bitmap對象
*/
public Bitmap parseUrl(String url, int position) {
Bitmap cacheBitmap = getBitmapFromCache(url);
if (cacheBitmap != null) {
Log.i(tag, "從記憶體中擷取圖檔");
return cacheBitmap;
}
Bitmap localBitmap = getBitmapFromLocal(url);
if (localBitmap != null) {
Log.i(tag, "從硬碟中擷取圖檔");
return localBitmap;
}
getBitmapFromNet(url, position);
Log.i(tag, "從網絡擷取圖檔");
return null;
}
// 從記憶體中擷取圖檔資源
private Bitmap getBitmapFromCache(String url) {
Bitmap bitmap = lruCache.get(url);
return bitmap;
}
// 從本地擷取圖檔資源
private Bitmap getBitmapFromLocal(String url) {
// 從本地位址中擷取圖檔資源,并且存入記憶體中
String fileName = MD5Utils.md5(url).substring(10);
File file = new File(context.getCacheDir(), fileName);
try {
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
lruCache.put(url, bitmap);
return bitmap;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
// 從網絡擷取圖檔資源
private void getBitmapFromNet(String url, int position) {
// 開發中必須以線程池開啟線程,不能自己定義線程開啟,這樣友善管理,增加效率
newFixedThreadPool.execute(new ThreadTask(url, position));
}
/**
* 網絡擷取圖檔
* @author UPC
*
*/
private class ThreadTask implements Runnable {
private String url;
private int position;
public ThreadTask(String url, int position) {
this.url = url;
this.position = position;
}
@Override
public void run() {
try {
URL urlObject = new URL(url);
HttpURLConnection con = (HttpURLConnection) urlObject.openConnection();
con.setConnectTimeout(2000);
con.setReadTimeout(2000);
con.setRequestMethod("GET");
int code = con.getResponseCode();
if (code==200) {
InputStream in = con.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
//子線程不能更新UI
Message msg = Message.obtain();
msg.obj = bitmap;
msg.what = SUCCESS;
//儲存圖檔的标示,通過這個标示,然後再通過父控件的fingViewByTag()方法擷取到指定的控件
msg.arg1 = position;
handler.sendMessage(msg);
//儲存圖檔到記憶體
lruCache.put(url, bitmap);
//儲存圖檔到本地
writeToLocal(url, bitmap);
return;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//抛出異常,放松擷取圖檔失敗的消息
Message msg = Message.obtain();
msg.what = FAIL;
handler.sendMessage(msg);
}
}
public void writeToLocal(String url,Bitmap bitmap){
String fileName = MD5Utils.md5(url).substring(10);
File file = new File(context.getCacheDir(),fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 70, fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
調用時的邏輯
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case ImageCache.SUCCESS:
// 下載下傳成功
Bitmap bitmap = (Bitmap) msg.obj;
// 根據傳遞進去的索引去拿到,顯示這個圖檔的控件
int position = msg.arg1;
ImageView imageView = (ImageView) view
.findViewWithTag(position);
if (bitmap != null && imageView != null) {
imageView.setImageBitmap(BitmapUtil.toRoundBitmap(bitmap));
}
break;
case ImageCache.FAIL:
// 下載下傳失敗
Toast.makeText(mContext, "頭像擷取失敗", Toast.LENGTH_SHORT).show();
break;
}
}
};
2.對字元串進行MD5加密
package com.heima.zhbj55.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
public static String md5(String source){
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] md5Source = digest.digest(source.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : md5Source) {
int i = b & 0xff;// 擷取該位元組的低八位資訊, 11111111
String hexString = Integer.toHexString(i);
if (hexString.length() < 2) {
hexString = "0" + hexString;
}
sb.append(hexString);
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}
3.圖檔相關操作
(1)圖檔縮放
a.縮放圖檔普通
/**
* 縮放圖檔多指定比例
* @param path 圖檔路徑
* @param width 寬
* @param height 高
* @return
*/
public static Bitmap resizeImage(String path, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;// 不加載bitmap到記憶體中
BitmapFactory.decodeFile(path, options);
int outWidth = options.outWidth;
int outHeight = options.outHeight;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inSampleSize = 1;
if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0) {
int sampleSize = (outWidth / width + outHeight / height) / 2;
options.inSampleSize = sampleSize;
}
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
//使用Bitmap加Matrix來縮放
public static Bitmap resizeImage(Bitmap bitmap, int w, int h) {
Bitmap BitmapOrg = bitmap;
int width = BitmapOrg.getWidth();
int height = BitmapOrg.getHeight();
int newWidth = w;
int newHeight = h;
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// if you want to rotate the Bitmap
// matrix.postRotate(45);
Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
height, matrix, true);
return resizedBitmap;
}
b.防止OOM(據說)
/**
* 加載本地圖檔 防止oom
*
* @param filePath
* @param outWidth
* @param outHeight
* @return
*/
public static Bitmap readBitmapAutoSize(Context context, String filePath,
int outWidth, int outHeight) {
// outWidth和outHeight是目标圖檔的最大寬度和高度,用作限制
// BufferedInputStream bs = null;
FileInputStream fs = null;
BufferedInputStream bs = null;
try {
File newFile = new File(filePath);
if (!newFile.exists()) {
return null;
}
int rad = readPictureDegree(filePath);
try {
fs = new FileInputStream(filePath);
bs = new BufferedInputStream(fs);
if (fs != null && bs != null) {
BitmapFactory.Options options = setBitmapOption(context,
filePath, outWidth, outHeight);
if (rad != 0) {
return rotaingImageView(rad,
BitmapFactory.decodeStream(bs, null, options));
} else
return BitmapFactory.decodeStream(bs, null, options);
} else {
try {
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bs.close();
fs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public static Bitmap rotaingImageView(int angle, Bitmap mBitmap) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
Bitmap b = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(),
mBitmap.getHeight(), matrix, true);
return b;
}
public static int readPictureDegree(String imagePath) {
int imageDegree = 0;
try {
ExifInterface exifInterface = new ExifInterface(imagePath);
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
imageDegree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
imageDegree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
imageDegree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return imageDegree;
}
c.根據指定像素數來縮放
注:調用——opts.inSampleSize = computeSampleSize(opts, -1, 295000);
/**
* 縮放圖檔到指定比例
* @param options 目标圖檔的屬性對象
* @param minSideLength 不知道,用的時候傳入的是-1
* @param maxNumOfPixels 目标像素點
* @return
*/
public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
int roundedSize;
if (initialSize <= 8) {
roundedSize = 1;
while (roundedSize < initialSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initialSize + 7) / 8 * 8;
}
return roundedSize;
}
private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) {
double w = options.outWidth;
double h = options.outHeight;
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 :(int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
// return the larger one when there is no overlapping zone.
return lowerBound;
}
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}
d.最早自己寫的
(2)圖檔變形
/**
* 轉換圖檔成圓形
*
* @param bitmap
* 傳入Bitmap對象
* @return
*/
public static Bitmap toRoundBitmap(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float roundPx;
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
if (width <= height) {
roundPx = width / 2;
top = 0;
bottom = width;
left = 0;
right = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundPx = height / 2;
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
}
Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect src = new Rect((int) left, (int) top, (int) right,
(int) bottom);
final Rect dst = new Rect((int) dst_left, (int) dst_top,
(int) dst_right, (int) dst_bottom);
final RectF rectF = new RectF(dst);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, src, dst, paint);
return output;
}
4.中文轉換為拼音
注:需要第三方jar包【pinyin4j-2.5.0】
/**
* 漢字轉換位漢語拼音,英文字元不變
* @param chines 漢字
* @return 拼音
*/
public static String converterToSpell(String chines){
String pinyinName = "";
char[] nameChar = chines.toCharArray();
HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
for (int i = 0; i < nameChar.length; i++) {
if (nameChar[i] > 128) {
try {
pinyinName += PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0];
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
}else{
pinyinName += nameChar[i];
}
}
return pinyinName;
}
5.解析Excel
需要第三方開源包:jxl
File excel = new File(context.getCacheDir(),"areaid_v.xls");
//建立解析對象
Workbook book;
try {
book = Workbook.getWorkbook(excel);
} catch (Exception e) {
throw new RuntimeException("file not found");
}
//擷取第一張表格
Sheet sheet = book.getSheet(0);
Cell cellCityCode, cellCityName;
int row = 1;
while (true) {
//擷取第幾行第一列内容
cellCityCode = sheet.getCell(0, row);
//擷取第幾行第三列内容
cellCityName = sheet.getCell(2, row);
//這是退出邏輯,因情況而定
if (cellCityName.getContents().equals(address.getName())) {
address.setWeatherIndexCode(cellCityCode.getContents());
break;
}
if ("".equals(cellCityCode.getContents()) == true) //如果讀取的資料為空
break;
row++;
}
book.close();