您的位置:首页 > 其它

智慧北京第5天

2016-10-12 09:13 141 查看

1.三级缓存原理

 内存缓存, 优先加载, 速度最快
本地缓存, 次优先加载, 速度快
网络缓存, 不优先加载, 速度慢,浪费流量

①.网络加载

//网络读取数据
public class NetworkCacheUtils {
private HttpURLConnection coon;
private SdcardCacheUtils sdcardCacheUtils;
private RoomCacheUtils roomCacheUtils;
public NetworkCacheUtils(SdcardCacheUtils sdcardCacheUtils, RoomCacheUtils roomCacheUtils) {
this.sdcardCacheUtils = sdcardCacheUtils;
this.roomCacheUtils = roomCacheUtils;
}

// 根据传入的url给传入的ImageView设置图片
public void getBitmapFromNet(ImageView ivPic, String url) {
new BitmapTask().execute(ivPic, url);// 执行异步下载
}

public class BitmapTask extends AsyncTask<Object, Void, Bitmap> {

private ImageView imageView;
private String url;

// 执行前调用。初始化数据
@Override
protected void onPreExecute() {
super.onPreExecute();
}

//异步下载数据
@Override
protected Bitmap doInBackground(Object... params) {
imageView = (ImageView) params[0];
url = (String) params[1];
imageView.setTag(url);
return downloadBitmap(url);
}

//
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}

//当doInbackground下载完之后会将结果返回到这里(主线程运行)
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result != null) {
//获取绑定的Bitmap对象的url
String bindurl = (String) imageView.getTag();

// 防止图片的重用导致的错乱
if (url.equals(bindurl)) {
sdcardCacheUtils.saveDatatoSdcard(result, bindurl);//保存数据到本地
roomCacheUtils.setDatatoRoom(bindurl, result);//保存数据到内存
imageView.setImageBitmap(result);//设置图片
System.out.println("从网络拿到图片了。。。。");
}
}
}
}

/*
* 下载图片的逻辑
*/
private Bitmap downloadBitmap(String url) {
try {
coon = (HttpURLConnection) new URL(url).openConnection();
coon.setConnectTimeout(5000);
coon.setReadTimeout(5000);
coon.setRequestMethod("GET");
coon.connect();

int responseCode = coon.getResponseCode();
if (responseCode == 200) {
InputStream inputStream = coon.getInputStream();

//对图片进行压缩
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2 ;//宽高缩小为原来的2分之一
options.inPreferredConfig = Bitmap.Config.RGB_565;//设置图片的字节大小要求,565的最小
Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null,options);
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
coon.disconnect();
}
return null;
}
}

②.从网络读取的bitmap对象保存到本地中

public class SdcardCacheUtils {
private static final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/nzhbj";

public void saveDatatoSdcard(Bitmap bitmap, String url) {

String fileName;
try {
fileName = MD5Encoder.encode(url);//根据图片的url设置名字
File file = new File(path, fileName);//创建File对象
//如果没有父文件夹。则创建
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
//保存图片到流中	jpeg格式 100是不压缩
bitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
} catch (Exception e1) {
e1.printStackTrace();
}
}
//从Sdcard中获取bitmap对象
public Bitmap getDatabySdcard(String url){
try {
String fileName = MD5Encoder.encode(url);
File file = new File(path,fileName);
if(file.exists()){
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

      ③.将网络读取的bitmap保存到内存中

public class RoomCacheUtils {
private LruCache<String, Bitmap>lruCache; //使用最少最近算法

public  RoomCacheUtils(){
//设置lruCache缓存的大小一半为总内存的8分之一
float maxSize = Runtime.getRuntime().maxMemory()/8;//模拟器默认是16m
lruCache = new LruCache<String, Bitmap>((int)maxSize){
@Override
protected int sizeOf(String key, Bitmap value) {
//返回一张图片的大小
int rowBytes = value.getByteCount();
return rowBytes;
}
};

}
//保存对象在内存中
public void setDatatoRoom(String url , Bitmap bitmap ){
lruCache.put(url, bitmap);
}
//从内存中读取Bitmap对象
public Bitmap getDataByRoom(String url){
Bitmap bitmap = lruCache.get(url);
return bitmap;
}
}

④.获取三种缓存

public class MybitmpaUtils {
private NetworkCacheUtils networkCacheUtils;
private SdcardCacheUtils sdcardCacheUtils;
private RoomCacheUtils roomCacheUtils;
public MybitmpaUtils() {
roomCacheUtils = new RoomCacheUtils();
sdcardCacheUtils = new SdcardCacheUtils();
networkCacheUtils = new NetworkCacheUtils(sdcardCacheUtils,roomCacheUtils);
}

public void display(ImageView ivPic,String url){
ivPic.setImageResource(R.drawable.news_pic_default);//设置默认图片

//1.从内存中读取,最快
Bitmap bitmapRoom = roomCacheUtils.getDataByRoom(url);
if(bitmapRoom!=null){
ivPic.setImageBitmap(bitmapRoom);
System.out.println("从内存中读取到了");
return;
}

//2.从sdcard中读取。第二
Bitmap bitmap = sdcardCacheUtils.getDatabySdcard(url);
if(bitmap!=null){
ivPic.setImageBitmap(bitmap);
roomCacheUtils.setDatatoRoom(url, bitmap);//保存一份到内存中
System.out.println("从sdcard中读取到了");
return;
}

//3.从网络中读取,第三
networkCacheUtils.getBitmapFromNet(ivPic, url);
}

}


总结:内存缓存  2.3之前是设置软引用(强.软.弱.虚 -----对象在内存中保存强度依次减弱)
2.3之后系统也会考虑回收软引用的对象  解决方法:使用LRU算法 
软引用:

<span style="white-space: pre;">	//一般对象:HashMap<String, Bitmap> hashMap = new HashMap<String, Bitmap>();
<span style="white-space: pre;">	</span>//软引用对象:HashMap<String, SoftReference<Bitmap>>hashMap = new HashMap<String, SoftReference<Bitmap>>();
<span style="white-space: pre;">	</span>//SoftReference<Bitmap> reference = hashMap.get(url);</span>


LRU:

<span style="white-space:pre">	</span>private LruCache<String, Bitmap>lruCache; //使用最少最近算法
<span style="white-space:pre">	</span>lruCache.put(url, bitmap);//保存
<span style="white-space:pre">	</span>Bitmap bitmap = lruCache.get(url);//获取


使用了这些可能还会崩.还可以对图片进行压缩

<span style="white-space:pre">		</span>//对图片进行压缩
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2 ;//宽高缩小为原来的2分之一
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null,options);


2.极光推送.推送官网介绍

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: