SettingsProvider 之SettingsCache

转载请注明出处:http://blog.csdn.net/droyon/article/details/35558437

SettingsCache,此类注明了SettingsProvider的缓冲。会缓冲所有的当前请求访问的key值及其value。此缓冲区处在内存中,读取效率较高。

SettingsProvider支持多用户概念,每个用户都有至少三张表(System、Secure),每一张表都存在一个SettingsCache。

1、在手机启动时,会将SettingsProvider对应的数据库中的数据表的内容缓冲进来。

private void fullyPopulateCache(DatabaseHelper dbHelper, String table, SettingsCache cache) {
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor c = db.query(
            table,
            new String[] { Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE },
            null, null, null, null, null,
            "" + (MAX_CACHE_ENTRIES + 1) /* limit */);
        try {
            synchronized (cache) {
                cache.evictAll();
                cache.setFullyMatchesDisk(true);  // optimistic
                int rows = 0;
                while (c.moveToNext()) {
                    rows++;
                    String name = c.getString(0);
                    String value = c.getString(1);
                    cache.populate(name, value);
                }
                if (rows > MAX_CACHE_ENTRIES) {
                    // Somewhat redundant, as removeEldestEntry() will
                    // have already done this, but to be explicit:
                    cache.setFullyMatchesDisk(false);
                    Log.d(TAG, "row count exceeds max cache entries for table " + table);
                }
                if (LOCAL_LOGV) Log.d(TAG, "cache for settings table '" + table
                        + "' rows=" + rows + "; fullycached=" + cache.fullyMatchesDisk());
            }
        } finally {
            c.close();
        }
    }

2、SettingsCache extends LruCache<String, Bundle>

/**
     * In-memory LRU Cache of system and secure settings, along with
     * associated helper functions to keep cache coherent with the
     * database.
     * 在内存中缓存System,Secure的设置项,以及相关功能方法来保证和数据库的一致性。
     */
private boolean mCacheFullyMatchesDisk = false;  // has the whole database slurped. 标记内存LRU缓冲是否清空了整个数据库
cache.evictAll();//remove所有元素,回调entryRemoved(true,key,value)

3、putIfAbsent方法

 /**
         * Atomic cache population, conditional on size of value and if
         * we lost a race.
         *
         * @returns a Bundle to send back to the client from call(), even
         *     if we lost the race.
         */
        public Bundle putIfAbsent(String key, String value) {
            Bundle bundle = (value == null) ? NULL_SETTING : Bundle.forPair("value", value);
            if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) {//如果value为null,或者value的长度小于500字符
                synchronized (this) {
                    if (get(key) == null) {
                        put(key, bundle);//bundle可能:NULL_SETTINGS、Bundle.forPair("value", value)
                    }
                }
            }//【value不为null,且value的长度大于500,直接返回bundle,bundle为Bundle.forPair("value", value)】
            return bundle;
        }

4、populate(填充)

/**
         * Populates a key in a given (possibly-null) cache.
         * 填充cache中的关键字
         */
        public static void populate(SettingsCache cache, ContentValues contentValues) {
            if (cache == null) {
                return;
            }
            String name = contentValues.getAsString(Settings.NameValueTable.NAME);
            if (name == null) {
                Log.w(TAG, "null name populating settings cache.");
                return;
            }
            String value = contentValues.getAsString(Settings.NameValueTable.VALUE);
            cache.populate(name, value);
        }

5、检查重复

/**
         * For suppressing duplicate/redundant settings inserts early,
         * checking our cache first (but without faulting it in),
         * before going to sqlite with the mutation.
         * 在插入前,检查重复。在使用sqlite前,先检查cache
         * 是否为重复的值。
         */
        public static boolean isRedundantSetValue(SettingsCache cache, String name, String value) {
            if (cache == null) return false;
            synchronized (cache) {
                Bundle bundle = cache.get(name);
                if (bundle == null) return false;
                String oldValue = bundle.getPairValue();
                if (oldValue == null && value == null) return true;
                if ((oldValue == null) != (value == null)) return false;//神奇代码
                return oldValue.equals(value);
            }
        }

SettingsProvider 之SettingsCache

时间: 2024-08-25 09:22:21

SettingsProvider 之SettingsCache的相关文章

SettingsProvider 它SettingsCache

转载请注明出处:http://blog.csdn.net/droyon/article/details/35558437 SettingsCache,如指出,SettingsProvider缓冲.这将缓冲所有当前请求访问key值及其value.此缓冲区处在内存中,读取效率较高. SettingsProvider支持多用户概念,每一个用户都有至少三张表(System.Secure).每一张表都存在一个SettingsCache. 1.在手机启动时,会将SettingsProvider相应的数据库中

SettingsProvider之增删改查

转载请注明出处:http://blog.csdn.net/droyon/article/details/35558697 当delete或者update时,需要清空缓冲区并重新加载数据. 1.invalidateCache()//得到当前用户的SettingsCache,remove所有. public SettingsCache cacheForTable(final int callingUser, String tableName) { if (TABLE_SYSTEM.equals(ta

SettingsProvider之Settings.System(Secure)内部类

转载请注明出处:http://blog.csdn.net/droyon/article/details/35558783 SettingsProvider采用了双缓冲,我们前面说过SettingsProvider中存在SettingsCache缓冲区,那么在Settings.java中还存在另外一个缓冲区,它就是NameValueCache. 1. NameValueTable用于描述SettingsProvider的数据表,封装了putString方法. /** * Common base f

Android默认输入法语言的修改以及SettingsProvider作用

Android源码中默认的有三种输入法:英文,中文,日文.对应的工程代码路径为:<android_root>/packages/inputmethods/LatinIME/<android_root>/packages/inputmethods/OpenWnn/<android_root>/packages/inputmethods/PinyinIME/ 一般情况下,默认都是选择的LatinIME输入法,但是Android系统默认都是选择系统语言作为输入法,比如我们要用

SettingsProvider 之 DatabaseHelper

转载请注明出处:http://blog.csdn.net/droyon/article/details/35558375 1.只为所有者创建global表. // Only create the global table for the singleton 'owner' user //只为所有者创建global table. if (mUserHandle == UserHandle.USER_OWNER) { createGlobalTable(db); } 2.//如果我们正在加密设备,只

Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建

在较早时期,我写过一篇文章<结合Control.FirefoxDialog控件,构造优秀的参数配置管理模块>,介绍过在我的Winform框架基础上集成的参数配置模块功能,但是参数模块的配置管理感觉还不够灵活,于是一直在寻找一个较好的替代者,用来结合FireFoxDialog界面一并展现,期间仔细研读过好几篇Codeproject网站上的关于配置管理的文章,但是总是觉得不够灵活或者简便.本文主要针对结合FireFoxDialog参数配置界面组件和SettingsProvider.net技术,实现

Settings中的xml中的值与SettingsProvider中default.xml中的值的区别

最近在看Settings中的一个默认值的时候,发现有两个地方使用,有点疑问. 这两个defaultval有啥区别? ./res/xml/sound_settings.xml:109 104     <CheckBoxPreference 105             android:key="sound_effects" 106             android:title="@string/sound_effects_enable_title" 10

Kitkat的加密功能对应用做了什么?

本文只分析手机加密后,启动到输入密码的界面的流程. 一. 加密后,系统服务针对加密功能做了什么? 最先启动的是SystemServer,调用ServerThread的initAndLoop()方法,开始启动系统的其他的服务. 在该文件中搜索"crypt",得到如下内容: 1. private static final String ENCRYPTING_STATE = "trigger_restart_min_framework"; private static f

Interview

下面的题是供大家查漏补缺用的,真正的把这些题搞懂了,才能"以不变应万变". 回答问题的时候能联系做过项目的例子是最好的,有的问题后面我已经补充联系到项目中的对应的案例了. 1.简述 private. protected. public. internal 修饰符的访问权限.  private : 私有成员, 在类的内部才可以访问. protected : 保护成员,该类内部和继承类中可以访问. public : 公共成员,完全公开,没有访问限制. internal: 当前程序集内可以访