首页 技术 正文
技术 2022年11月15日
0 收藏 565 点赞 3,393 浏览 7869 个字

SharePreference工具类

  1. /**
    * SharePreference封装
    *
    */
    public class PrefUtils {
    public static final String PREF_NAME = "config";
    public static boolean getBoolean(Context ctx, String key,
    boolean defaultValue) {
    SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
    Context.MODE_PRIVATE);
    return sp.getBoolean(key, defaultValue);
    }
    public static void setBoolean(Context ctx, String key, boolean value) {
    SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
    Context.MODE_PRIVATE);
    sp.edit().putBoolean(key, value).commit();
    }
    public static String getString(Context ctx, String key, String defaultValue) {
    SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
    Context.MODE_PRIVATE);
    return sp.getString(key, defaultValue);
    }
    public static void setString(Context ctx, String key, String value) {
    SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
    Context.MODE_PRIVATE);
    sp.edit().putString(key, value).commit();
    }
    }

缓存工具类

  1. public class CacheUtils {
    /**
    * 缓存原理:设置缓存 key 是url, value是json(解析出来的)
    */
    public static void setCache(String key, String value, Context ctx) {
    PrefUtils.setString(ctx, key, value);
    // 可以将缓存放在文件中, 文件名就是Md5(url), 文件内容是json
    }
    /**
    * 获取缓存 key 是url
    */
    public static String getCache(String key, Context ctx) {
    return PrefUtils.getString(ctx, key, null);
    }
    }

用法:1.在请求完网络,获取json数据后保存起来

  1. private void getDataFromServer() {
    HttpUtils utils = new HttpUtils();
    utils.send(HttpMethod.GET, GlobalContants.PHOTOS_URL,
    new RequestCallBack<String>() {
    @Override
    public void onSuccess(ResponseInfo<String> responseInfo) {
    String result = (String) responseInfo.result;
    parseData(result);
    // 设置缓存
    CacheUtils.setCache(GlobalContants.PHOTOS_URL, result,
    mActivity);
    }
    @Override
    public void onFailure(HttpException error, String msg) {
    Toast.makeText(mActivity, msg, Toast.LENGTH_SHORT)
    .show();
    error.printStackTrace();
    }
    });
    }

2.在初始化数据的时候判断,可以直接解析数据,也可以什么都不做,然后获取网络数据看有没有最新的

  1. public void initData() {
    String cache = CacheUtils
    .getCache(GlobalContants.PHOTOS_URL, mActivity);
    if (!TextUtils.isEmpty(cache)) {
    // parseData(cache);
    }
    getDataFromServer();
    }

解析数据

  1. protected void parseData(String result) {
    Gson gson = new Gson();
    PhotosData data = gson.fromJson(result, PhotosData.class);
    mPhotoList = data.data.news;// 获取组图列表集合
    if (mPhotoList != null) {
    mAdapter = new PhotoAdapter();
    lvPhoto.setAdapter(mAdapter);
    gvPhoto.setAdapter(mAdapter);
    }
    }

三级缓存13.缓存、三级缓存、内存溢出、AsyncTask

– 内存缓存, 优先加载, 速度最快
– 本地缓存, 次优先加载, 速度快
– 网络缓存, 不优先加载, 速度慢,浪费流量 服务器端下载的图片是使用 Http的缓存机制,每次执行将本地图片的时间发送给服务器,如果返回码是 304,说明服务端的图片和本地的图片是相同的,直接使用本地保存的图片,如果返回码是 200,则开始下载新的图片并实现缓存。在从服务器获取到图片后,需要再在本地和内存中分别存一份,这样下次直接就可以从内存中直接获取了,这样就加快了显示的速度,提高了用户的体验。 内存溢出OOM导致内存泄漏主要的原因是,先前申请了内存空间而忘记了释放。如果程序中存在对无用对象的引用,那么这些对象就会驻留内存,消耗内存,因为无法让垃圾回收器GC验证这些对象是否不再需要。如果存在对象的引用,这个对象就被定义为”有效的活动”,同时不会被释放。要确定对象所占内存将被回收,我们就要务必确认该对象不再会被使用。典型的做法就是把对象数据成员设为null或者从集合中移除该对象。但当局部变量不需要时,不需明显的设为null,因为一个方法执行完毕时,这些引用会自动被清理

内存溢出(oom) out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。memory leak会最终会导致out of memory!

解决方法1:java中的引用(使用软引用)
13.缓存、三级缓存、内存溢出、AsyncTask
    – 强引用 垃圾回收器不会回收, java默认引用都是强引用
    – 软引用 SoftReference   在内存不够时,垃圾回收器会考虑回收
    – 弱引用 WeakReference  在内存不够时,垃圾回收器会优先回收
    – 虚引用 PhantomReference  在内存不够时,垃圾回收器最优先回收

注意: Android2.3+, 系统会优先将SoftReference的对象提前回收掉, 即使内存够用

 解决方法2:LruCache     least recentlly use 最少最近使用算法

会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定

解决方法3:图片压缩

 xutils就是这个原理,现在不用xutils,现在自定义几个工具类 1.自定义加载工具类

  1. public class MyBitmapUtils {
    NetCacheUtils mNetCacheUtils;
    LocalCacheUtils mLocalCacheUtils;
    MemoryCacheUtils mMemoryCacheUtils;
    public MyBitmapUtils() {
    mMemoryCacheUtils = new MemoryCacheUtils();
    mLocalCacheUtils = new LocalCacheUtils();
    mNetCacheUtils = new NetCacheUtils(mLocalCacheUtils, mMemoryCacheUtils);
    }
    public void display(ImageView ivPic, String url) {
    ivPic.setImageResource(R.drawable.news_pic_default);// 设置默认加载图片
    Bitmap bitmap = null;
    // 从内存读
    bitmap = mMemoryCacheUtils.getBitmapFromMemory(url);
    if (bitmap != null) {
    ivPic.setImageBitmap(bitmap);
    System.out.println("从内存读取图片啦...");
    return;
    }
    // 从本地读
    bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
    if (bitmap != null) {
    ivPic.setImageBitmap(bitmap);
    System.out.println("从本地读取图片啦...");
    mMemoryCacheUtils.setBitmapToMemory(url, bitmap);// 将图片保存在内存
    return;
    }
    // 从网络读
    mNetCacheUtils.getBitmapFromNet(ivPic, url);
    }
    }

2.网络缓存、AsyncTask

  1. public class NetCacheUtils {
    private LocalCacheUtils mLocalCacheUtils;
    private MemoryCacheUtils mMemoryCacheUtils;
    public NetCacheUtils(LocalCacheUtils localCacheUtils,
    MemoryCacheUtils memoryCacheUtils) {
    mLocalCacheUtils = localCacheUtils;
    mMemoryCacheUtils = memoryCacheUtils;
    }
    /**
    * 从网络下载图片
    *
    * @param ivPic
    * @param url
    */
    public void getBitmapFromNet(ImageView ivPic, String url) {
    new BitmapTask().execute(ivPic, url);// 启动AsyncTask,
    // 参数会在doInbackground中获取
    }
    /**
    * Handler和线程池的封装
    *
    * 第一个泛型: 参数类型 第二个泛型: 更新进度的泛型, 第三个泛型是onPostExecute的返回结果
    *
    * @author Kevin
    *
    */
    class BitmapTask extends AsyncTask<Object, Void, Bitmap> {
    private ImageView ivPic;
    private String url;
    /**
    * 后台耗时方法在此执行, 子线程
    */
    @Override
    protected Bitmap doInBackground(Object... params) {
    ivPic = (ImageView) params[0];
    url = (String) params[1];
    ivPic.setTag(url);// 将url和imageview绑定
    return downloadBitmap(url);
    }
    /**
    * 更新进度, 主线程
    */
    @Override
    protected void onProgressUpdate(Void... values) {
    super.onProgressUpdate(values);
    }
    /**
    * 耗时方法结束后,执行该方法, 主线程
    */
    @Override
    protected void onPostExecute(Bitmap result) {
    if (result != null) {
    String bindUrl = (String) ivPic.getTag();
    if (url.equals(bindUrl)) {// 确保图片设定给了正确的imageview
    ivPic.setImageBitmap(result);
    mLocalCacheUtils.setBitmapToLocal(url, result);// 将图片保存在本地
    mMemoryCacheUtils.setBitmapToMemory(url, result);// 将图片保存在内存
    System.out.println("从网络缓存读取图片啦...");
    }
    }
    }
    }
    /**
    * 下载图片
    *
    * @param url
    * @return
    */
    private Bitmap downloadBitmap(String url) {
    HttpURLConnection conn = null;
    try {
    conn = (HttpURLConnection) new URL(url).openConnection();
    conn.setConnectTimeout(5000);
    conn.setReadTimeout(5000);
    conn.setRequestMethod("GET");
    conn.connect();
    int responseCode = conn.getResponseCode();
    if (responseCode == 200) {
    InputStream inputStream = conn.getInputStream();//图片压缩处理
    BitmapFactory.Options option = new BitmapFactory.Options();
    option.inSampleSize = 2;//宽高都压缩为原来的二分之一, 此参数需要根据图片要展示的大小来确定
    option.inPreferredConfig = Bitmap.Config.RGB_565;//设置图片格式Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, option);
    return bitmap;
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    conn.disconnect();
    }
    return null;
    }
    }

3.本地缓存(SD卡),一般会以MD5加密文件名

  1. public class LocalCacheUtils {
    public static final String CACHE_PATH = Environment
    .getExternalStorageDirectory().getAbsolutePath() + "/zhbj_cache_52";
    /**
    * 从本地sdcard读图片
    */
    public Bitmap getBitmapFromLocal(String url) {
    try {
    String fileName = MD5Encoder.encode(url);
    File file = new File(CACHE_PATH, fileName);
    if (file.exists()) {
    Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
    file));//decodeStream放的是输入输出流
    return bitmap;
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }
    /**
    * 向sdcard写图片
    *
    * @param url
    * @param bitmap
    */
    public void setBitmapToLocal(String url, Bitmap bitmap) {
    try {
    String fileName = MD5Encoder.encode(url);
    File file = new File(CACHE_PATH, fileName);
    File parentFile = file.getParentFile();
    if (!parentFile.exists()) {// 如果文件夹不存在, 创建文件夹
    parentFile.mkdirs();
    }
    // 将图片保存在本地
    bitmap.compress(CompressFormat.JPEG, 100,
    new FileOutputStream(file));//100是质量
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

3.内存缓存:内存中使用LRUCache是最合适的。如果用HashMap来实现,不是不可以,但需要注意在合适的时候释放缓存。至于具体怎么释放,我没考虑过,但用软引用的问题在于,你很难控制缓存的大小,也就是说,只有等到你的内存快要撑爆,你的图片缓存才会被回收。是不是感觉傻傻的?

  1. public class MemoryCacheUtils {
    // private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new
    // HashMap<String, SoftReference<Bitmap>>();//一开始使用map,后来使用软引用
    private LruCache<String, Bitmap> mMemoryCache;
    public MemoryCacheUtils() {
    long maxMemory = Runtime.getRuntime().maxMemory() / 8;//主流都是分配16m的8/1
    mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {
    @Override
    protected int sizeOf(String key, Bitmap value) {
    int byteCount = value.getRowBytes() * value.getHeight();// 获取图片占用内存大小
    return byteCount;
    }
    };
    }
    /**
    * 从内存读
    *
    * @param url
    */
    public Bitmap getBitmapFromMemory(String url) {
    // SoftReference<Bitmap> softReference = mMemoryCache.get(url);
    // if (softReference != null) {
    // Bitmap bitmap = softReference.get();
    // return bitmap;
    // }
    return mMemoryCache.get(url);
    }
    /**
    * 写内存
    *
    * @param url
    * @param bitmap
    */
    public void setBitmapToMemory(String url, Bitmap bitmap) {
    // SoftReference<Bitmap> softReference = new
    // SoftReference<Bitmap>(bitmap);
    // mMemoryCache.put(url, softReference);
    mMemoryCache.put(url, bitmap);
    }
    }

      


       来自为知笔记(Wiz)

附件列表

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,487
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,736
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,486
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,126
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,287