精华内容
下载资源
问答
  • 一、Android中的缓存策略Android缓存,主要的就是内存缓存和硬盘缓存。不管是内存缓存还是硬盘缓存,它们的缓存大小都是有限的。当缓存满了之后,再想其添加缓存,这个时候就需要删除一些旧的缓存并添加新的缓存。...

    一、Android中的缓存策略

    Android的缓存,主要的就是内存缓存和硬盘缓存。

    不管是内存缓存还是硬盘缓存,它们的缓存大小都是有限的。当缓存满了之后,再想其添加缓存,这个时候就需要删除一些旧的缓存并添加新的缓存。

    缓存策略主要包含缓存的添加、获取和删除这三类操作

    因此LRU(Least Recently Used)缓存算法便应运而生,LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象。

    采用LRU算法的缓存有两种:LrhCache和DisLruCache,分别用于实现内存缓存和硬盘缓存,其核心思想都是LRU缓存算法。

    二、LruCache的使用

    LruCache是Android 3.1所提供的一个缓存类,所以在Android中可以直接使用LruCache实现内存缓存。而DisLruCache目前在Android 还不是Android SDK的一部分,但Android官方文档推荐使用该算法来实现硬盘缓存。

    1.LruCache的介绍

    LruCache是个泛型类,主要算法原理是把最近使用的对象用强引用(即我们平常使用的对象引用方式)存储在 LinkedHashMap 中。

    当缓存满时,把最近最少使用的对象从内存中移除,并提供了get和put方法来完成缓存的获取和添加操作。

    2.LruCache的使用

    LruCache的使用非常简单,我们就已图片缓存为例。

    int maxMemory = (int) (Runtime.getRuntime().totalMemory()/1024);

    int cacheSize = maxMemory/8;

    mMemoryCache = new LruCache(cacheSize){

    @Override

    protected int sizeOf(String key, Bitmap value) {

    return value.getRowBytes()*value.getHeight()/1024;

    }

    };

    ①设置LruCache缓存的大小,一般为当前进程可用容量的1/8。

    ②重写sizeOf方法,计算出要缓存的每张图片的大小。

    注意:缓存的总容量和每个缓存对象的大小所用单位要一致。

    三、LruCache的实现原理

    LruCache的核心思想很好理解,就是要维护一个缓存对象列表,其中对象列表的排列方式是按照访问顺序实现的,即一直没访问的对象,将放在队尾,即将被淘汰。而最近访问的对象将放在队头,最后被淘汰。

    e6e456752d3d

    1.png

    那么这个队列到底是由谁来维护的,前面已经介绍了是由LinkedHashMap来维护。

    LinkedHashMap

    容器类框架分析(5)(java)LinkedHashMap 源码分析

    LinkedHashMap是由数组+双向链表的数据结构来实现的。其中双向链表的结构可以实现访问顺序和插入顺序,使得LinkedHashMap中的对按照一定顺序排列起来。

    通过下面构造函数来指定LinkedHashMap中双向链表的结构是访问顺序还是插入顺序。

    public LinkedHashMap(int initialCapacity,

    float loadFactor,

    boolean accessOrder) {

    super(initialCapacity, loadFactor);

    this.accessOrder = accessOrder;

    }

    其中accessOrder设置为true则为访问顺序,为false,则为插入顺序。

    以具体例子解释:

    当设置为true时

    public static final void main(String[] args) {

    LinkedHashMap map = new LinkedHashMap<>(0, 0.75f, true);

    map.put(0, 0);

    map.put(1, 1);

    map.put(2, 2);

    map.put(3, 3);

    map.put(4, 4);

    map.put(5, 5);

    map.put(6, 6);

    map.get(1);

    map.get(2);

    for (Map.Entry entry : map.entrySet()) {

    System.out.println(entry.getKey() + ":" + entry.getValue());

    }

    }

    输出结果:

    0:0

    3:3

    4:4

    5:5

    6:6

    1:1

    2:2

    即最近访问的最后输出,那么这就正好满足的LRU缓存算法的思想。可见LruCache巧妙实现,就是利用了LinkedHashMap的这种数据结构。

    LruCache(int maxSize)

    下面我们在LruCache源码中具体看看,怎么应用LinkedHashMap来实现缓存的添加,获得和删除的。

    public LruCache(int maxSize) {

    if (maxSize <= 0) {

    throw new IllegalArgumentException("maxSize <= 0");

    }

    this.maxSize = maxSize;

    this.map = new LinkedHashMap(0, 0.75f, true);

    }

    从LruCache的构造函数中可以看到正是用了LinkedHashMap的访问顺序。

    put()方法

    public final V put(K key, V value) {

    //不可为空,否则抛出异常

    if (key == null || value == null) {

    throw new NullPointerException("key == null || value == null");

    }

    V previous;

    synchronized (this) {

    //插入的缓存对象值加1

    putCount++;

    //增加已有缓存的大小

    size += safeSizeOf(key, value);

    //向map中加入缓存对象

    previous = map.put(key, value);

    //如果已有缓存对象,则缓存大小恢复到之前

    if (previous != null) {

    size -= safeSizeOf(key, previous);

    }

    }

    //entryRemoved()是个空方法,可以自行实现

    if (previous != null) {

    entryRemoved(false, key, previous, value);

    }

    //调整缓存大小(关键方法)

    trimToSize(maxSize);

    return previous;

    }

    可以看到put()方法并没有什么难点,重要的就是在添加过缓存对象后,调用 trimToSize()方法,来判断缓存是否已满,如果满了就要删除近期最少使用的算法。

    trimToSize()方法

    public void trimToSize(int maxSize) {

    //死循环

    while (true) {

    K key;

    V value;

    synchronized (this) {

    //如果map为空并且缓存size不等于0或者缓存size小于0,抛出异常

    if (size < 0 || (map.isEmpty() && size != 0)) {

    throw new IllegalStateException(getClass().getName()

    + ".sizeOf() is reporting inconsistent results!");

    }

    //如果缓存大小size小于最大缓存,或者map为空,不需要再删除缓存对象,跳出循环

    if (size <= maxSize || map.isEmpty()) {

    break;

    }

    //迭代器获取第一个对象,即队尾的元素,近期最少访问的元素

    Map.Entry toEvict = map.entrySet().iterator().next();

    key = toEvict.getKey();

    value = toEvict.getValue();

    //删除该对象,并更新缓存大小

    map.remove(key);

    size -= safeSizeOf(key, value);

    evictionCount++;

    }

    entryRemoved(true, key, value, null);

    }

    }

    trimToSize()方法不断地删除LinkedHashMap中队尾的元素,即近期最少访问的,直到缓存大小小于最大值。

    当调用LruCache的get()方法获取集合中的缓存对象时,就代表访问了一次该元素,将会更新队列,保持整个队列是按照访问顺序排序。这个更新过程就是在LinkedHashMap中的get()方法中完成的。

    get()方法

    public final V get(K key) {

    //key为空抛出异常

    if (key == null) {

    throw new NullPointerException("key == null");

    }

    V mapValue;

    synchronized (this) {

    //获取对应的缓存对象

    //get()方法会实现将访问的元素更新到队列头部的功能

    mapValue = map.get(key);

    if (mapValue != null) {

    hitCount++;

    return mapValue;

    }

    missCount++;

    }

    中LinkedHashMap的get()方法如下:

    public V get(Object key) {

    LinkedHashMapEntry e = (LinkedHashMapEntry)getEntry(key);

    if (e == null)

    return null;

    //实现排序的关键方法

    e.recordAccess(this);

    return e.value;

    }

    调用recordAccess()方法如下:

    void recordAccess(HashMap m) {

    LinkedHashMap lm = (LinkedHashMap)m;

    //判断是否是访问排序

    if (lm.accessOrder) {

    lm.modCount++;

    //删除此元素

    remove();

    //将此元素移动到队列的头部

    addBefore(lm.header);

    }

    }

    由此可见LruCache中维护了一个集合LinkedHashMap,该LinkedHashMap是以访问顺序排序的。当调用put()方法时,就会在结合中添加元素,并调用trimToSize()判断缓存是否已满,如果满了就用LinkedHashMap的迭代器删除队尾元素,即近期最少访问的元素。当调用get()方法访问缓存对象时,就会调用LinkedHashMap的get()方法获得对应集合元素,同时会更新该元素到队头。

    参考

    展开全文
  • 后台缓存进程:不需要占用cpu资源,会在RAM中写入一部分数据,当下次打开这个应用时会快一些,当然也会占用一点内存,如果手机内存够大对速度性能不会有影响,如果内存不够那么会触发android的内存回收机制,优先杀...

    正在运行的进程:需要占用一定的cpu资源和RAM(内存)空间,多少的话看是什么应用,要消耗一定的电量,影响手机速度等性能。

    后台缓存的进程:不需要占用cpu资源,会在RAM中写入一部分数据,当下次打开这个应用时会快一些,当然也会占用一点内存,如果手机内存够大对速度性能不会有影响,如果内存不够那么会触发android的内存回收机制,优先杀掉这些进程(和java的垃圾回收机制相似),会耗一点点电,几乎没什么影响,只是在内存的某些位上写了地址数据,每隔一段时间过一遍电脉冲,刷新来保持数据。

    转载于:https://www.cnblogs.com/homg/p/3345022.html

    展开全文
  • Android 三级缓存机制:1、内存缓存 (LruCache算法)2、本地缓存 (File存储)3、网络缓存 (网络请求)Android缓存策略:缓存策略一般包括缓存的添加、获取、删除。缓存的添加和获取很容易懂,为什么要删除呢?无论是内存...

    Android 三级缓存机制:

    1、内存缓存 (LruCache算法)

    2、本地缓存  (File存储)

    3、网络缓存  (网络请求)

    Android缓存策略:

    缓存策略一般包括缓存的添加、获取、删除。缓存的添加和获取很容易懂,为什么要删除呢?无论是内存缓存还是硬盘缓存,缓存大小都是有限的,如果缓存满了,想要加进新的缓存,就需要删除一部分缓存,添加新的缓存。

    LruCache:Least rencently used 顾名思义:近期最少使用算法。LruCache和DisLruCache两个类,分别用于内存和硬盘缓存。核心思想是当缓存空间满了之后,会删除最近最少使用的缓存。

    一、内存缓存:LruCache

    LruCache是Android3.1实现的缓存类,所以android可以直接使用它来实现内存缓存。DisLruCache不是SDK中的一部分。

    1、LruCache的使用

    LruCache的原理是将缓存对象作为强引用,保存在LinkedHashMap中,当缓存满了之后,将对象从Map中移除,重新通过put方法添加新的缓存,get方法获取缓存。

    以图片缓存为例:int maxMemory = (int) (Runtime.getRuntime().totalMemory()/1024);

    int cacheSize = maxMemory/8;

    mMemoryCache = new LruCache(cacheSize){

    @Override

    protected int sizeOf(String key, Bitmap value) {

    return value.getRowBytes()*value.getHeight()/1024;

    }

    };

    1、设置LruCache缓存的大小,一般为当前进程可用的1/8。

    2、重写sizeOf方法,计算出缓存每张图片的大小

    2、LruCache的原理

    LruCache的核心思想就是维护一个缓存对象的队列,该队列由LinkedHashMap维护。一直没访问的对象放在队尾,最新访问的放在队首,当队列满了之后,从队尾开始淘汰,队首的最后淘汰。

    用别人的一个图形象说明:

    d213507779fb

    LruCache的源码里运用了LinkedHashMap的存取实现了缓存的添加(put)和获取(get)。

    put()方法public final V put(K key, V value) {

    //不可为空,否则抛出异常        if (key == null || value == null) {

    throw new NullPointerException("key == null || value == null");

    }

    V previous;

    synchronized (this) {

    //插入的缓存对象值加1            putCount++;

    //增加已有缓存的大小            size += safeSizeOf(key, value);

    //向map中加入缓存对象            previous = map.put(key, value);

    //如果已有缓存对象,则缓存大小恢复到之前            if (previous != null) {

    size -= safeSizeOf(key, previous);

    }

    }

    //entryRemoved()是个空方法,可以自行实现        if (previous != null) {

    entryRemoved(false, key, previous, value);

    }

    //调整缓存大小(关键方法)        trimToSize(maxSize);

    return previous;

    }

    从代码可以看出,在添加缓存之后,调用了trimToSize方法,判断缓存是否已满,来判断缓存是否已满,如果满了就运用LruCache算法,删除队尾的缓存。public void trimToSize(int maxSize) {

    //死循环        while (true) {

    K key;

    V value;

    synchronized (this) {

    //如果map为空并且缓存size不等于0或者缓存size小于0,抛出异常                if (size < 0 || (map.isEmpty() && size != 0)) {

    throw new IllegalStateException(getClass().getName()

    + ".sizeOf() is reporting inconsistent results!");

    }

    //如果缓存大小size小于最大缓存,或者map为空,不需要再删除缓存对象,跳出循环                if (size <= maxSize || map.isEmpty()) {

    break;

    }

    //迭代器获取第一个对象,即队尾的元素,近期最少访问的元素                Map.Entry toEvict = map.entrySet().iterator().next();

    key = toEvict.getKey();

    value = toEvict.getValue();

    //删除该对象,并更新缓存大小                map.remove(key);

    size -= safeSizeOf(key, value);

    evictionCount++;

    }

    entryRemoved(true, key, value, null);

    }

    }

    总结:LruCache只要就是维护了一个LinkedHashMap。当调用put方法时,向队列中加入缓存对象,然后调用trimToSize()判断缓存时候已满,如果满了,用LinkedHashMap的迭代器从队尾移除最近使用最少的缓存。获取缓存时调用get(),调用 LinkedHashMap的get方法,并将获取的数据更新到队首。

    二、本地缓存

    通过异步网络请求,获取网络资源

    展开全文
  • 在网上找到相关资料,然后写了这个demo,实验一键清除缓存成功!
  • 方法:在AndroidManifest.xml中,给四大组件中指定android:process属性例子:包名com.xxx1.android:process=“:remote”2.android:process=“com.xxx.remote”安卓默认进程名:com.xxx1.进程名:com.xxx:remote,...

    方法:

    在AndroidManifest.xml中,给四大组件中指定android:process属性

    例子:包名com.xxx

    1.android:process=“:remote”

    2.android:process=“com.xxx.remote”

    安卓默认进程名:com.xxx

    1.进程名:com.xxx:remote,当前应用的私有进程,其它应用的组件不能和它跑在一个进程

    2.进程名:com.xxx.remote,全局进程,其它应用可以通过ShareUID方式和它跑在一个进程

    adb shell ps | grep com.xxx 查看应用下的进程

    不同的进程访问同一个类的对象,会产生多个副本

    多进程带来的问题

    1.静态成员和单利模式完全失效(进程与进程之间不共享内存的数据)

    2.线程同步机制完全失效(锁的不是同一个对象)

    3.SharedPreferences可靠性下降

    4.Application多次创建

    进程通信方式

    1.intent

    2.共享文件

    3.SharedPreferences(可靠性下降,具体见下面sp多进程例子)

    4.SQLite ,解决3可靠性下降的问题

    sp多进程例子

    有A,B两个Activity,对sp的同一个key进行操作

    首先,A向sp写入值,并读取,没问题

    接下来,从A跳进B,读取sp,结果正确

    然后,在B中向sp写入值,并读取,没问题

    最后,返回A,在读取sp的值,发现值并没有改变(还是第一次在A中读取的值,而不是B修改后的值)

    原理分析

    SP使用了缓存的机制,会先把数据保存在内存中,在读取的时候直接从内存中读取,而写的时候才会保存到文件

    多进程之间内存不可见

    注:即使使用MODE_MULTI_PROCESS也不能保证进程间的同步

    sp存储的内容是没有长度限制的,因为它实际上是一个xml文件,而xml文件的value是不会限制长度的

    跨进程通信的测试用例(代码在ThirdJar的com.sf.service下)

    Service向Activity传递数据的方法

    1.广播

    2.通过bindservice,同时在Service中创建一个Binder对象和一个接口,在onServiceConnected回调中通过binder得到Service对象,然后对这个接口进行监听,就能得到Service传递过来的数据

    一个Activity,一个Service

    同一个进程中

    1,2均可行

    对service加android:process属性,两个进程

    1 可行

    2 报错 java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.sf.service.PlayService$MyBinder

    PlayService ps = ((PlayService.MyBinder) binder).getService(); 报错代码

    如果一个应用有多个进程,则我们在彻底退出程序时,只会销毁退出界面所在的进程,利用此特点,可以将Service放在其它的进程中,这样在程序退出后,Service仍可以正常运行。当然如果直接杀死程序,多个进程会同时被销毁

    展开全文
  • 做为应用开发者,对于进程生命周期和进程中的内存回收是透明的,但了解生命周期对加深对Andorid体系的理解很有帮助一、 进程生命周期Android系统将尽量长时间地保持应用进程,但为了新建进程或运行更重要的进程,...
  • 它是一个为Android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。 它可以缓存普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 byte数据。 项目...
  • 但是,如果我最小化此应用程序,由于某种原因其“缓存的后台进程”超过200mbs!有时250 …似乎完全不必要,因为该应用程序在全新安装时会快速加载闪电当应用程序最小化(onbackpressed等)时,如何清除此缓存解决方法:您...
  • Android缓存数据清理

    千次阅读 2017-05-12 13:13:12
    Android缓存的作用可以参考这篇文章:android缓存数据到本地放在哪儿最好? 应用程序在运行的过程中如果需要向手机上保存数据,一般是把数据保存在SDcard中的。大部分应用是直接在SDCard的根目录下创建一个文件夹,...
  • Android缓存机制&缓存框架——ACache

    千次阅读 2016-09-09 21:54:38
    Android开发本质上就是手机和互联网中的web服务器之间进行通信,就必然需要从服务端获取数据,而反复通过网络获取数据是比较耗时的,特别是访问比较多的时候,会极大影响了性能,Android中可通过二级缓存来减少频繁...
  • 1. Android 进程 默认情况下,同一 APP 的所有组件均运行在相同的进程中,但是也可以根据...内存不足的情况下,Android 系统会选择 kill 某一进程来释放该进程占用的内存,供其它为用户提供更为紧急服务的进程使...
  • 一、Android 进程优先级、 二、前台进程、 三、可见进程、 四、服务进程、 五、后台进程、 六、空进程
  • 概述LRU(Least Recently Used)近期最少使用的算法,它的核心...LruCache的使用//①设置LruCache缓存的大小,一般为当前进程可用容量的1/8。//②重写sizeOf方法,计算出要缓存的每张图片的大小。int maxMemory = (i...
  • 关于Android的三级缓存,其中主要的就是内存缓存和硬盘缓存。这两种缓存机制的实现都应用到了LruCache算法,今天我们就从使用到源码解析,来彻底理解Android中的缓存机制。 一、Android中的缓存策略 一般来说,...
  • Android进程保活·设置前台Service,提升App进程优先级 Android进程 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 (Visible process) 服务进程 ...
  • Android缓存机制&一个缓存框架推荐

    万次阅读 多人点赞 2016-06-17 07:53:12
    1、先推荐一个轻量级缓存框架——ACache(ASimpleCache) ACache介绍: ACache类似于SharedPreferences,但是比SharedPreferences功能更加强大,SharedPreferences只能保存一些基本数据类型、Serializable、Bundle等...
  • Android缓存机制详解

    千次阅读 2018-05-06 19:46:12
    一、Android中的缓存策略一般来说,缓存策略主要包含缓存的添加、获取和删除这三类操作。如何添加和获取缓存这个比较好理解,那么为什么还要删除缓存呢?这是因为不管是内存缓存还是硬盘缓存,它们的缓存大小都是...
  • Android守护进程

    千次阅读 2018-11-07 22:59:14
    本文主要讲解一些android比较常用的守护进程的方法。 实现思想: 1.保活,通过提高进程优先级,降低进程被杀死的概率 2.拉起,进程被杀死后,进行拉起 相关基础知识 Android进程优先级 在Android中,进程...
  • 彻底解析Android缓存机制——LruCache Ruheng 关注2017.02.25 17:09* 字数 1373 阅读 10060评论 24喜欢 79关于Android的三级缓存,其中主要的就是内存缓存和硬盘缓存。这两种缓存机制的实现都应用到了LruCache...
  • Android进程保活 Android进程 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 (Visible process) 服务进程 (Service process) 后台进程 (Background ...
  • Android进程保活

    2021-04-26 19:43:21
    1 Android进程的优先级 Foreground process Visible process Service process Background process Empty process 唯一目的:做缓存,缩短下次运行组件所需的启动时间 2 Android进程的回收策略 Low memory killer...
  • Android进程保活·设置前台Service,提升App进程优先级 Android进程 此文章代码Github上有提交: 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 ...
  • Android进程保活·1像素且透明Activity提升App进程优先级 Android进程 此文章代码Github上有提交:https://github.com/NorthernBrain/processKeep_Activity 首先你要知道Android中的进程以及它的优先级,下面来说明...
  • Android进程保活·设置前台Service,提升App进程优先级 Android进程 此文章代码Github上有提交:https://github.com/NorthernBrain/processKeep_Service/tree/master 首先你要知道Android中的进程以及它的优先级,...
  • 关于Android的三级缓存,其中主要的就是内存缓存和硬盘缓存。这两种缓存机制的实现都应用到了LruCache算法,今天我们就从使用到源码解析,来彻底理解Android中的缓存机制。 一、Android中的缓存策略 一般来说,...
  • 关于Android的三级缓存,其中主要的就是内存缓存和硬盘缓存。这两种缓存机制的实现都应用到了LruCache算法,今天我们就从使用到源码解析,来彻底理解Android中的缓存机制  ## **一、Android中的缓存策略** ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 49,681
精华内容 19,872
关键字:

安卓缓存进程