欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android SharedPreference的实现(2)

程序员文章站 2022-04-12 19:58:28
从sharedpreference中获取值以及从editor中设置值已经在sharedpreferences的具体实现(1)中具体说明,这节的主要目的就是理解sharedpreference的com...

从sharedpreference中获取值以及从editor中设置值已经在sharedpreferences的具体实现(1)中具体说明,这节的主要目的就是理解sharedpreference的commit过程。

代码1:
public boolean commit() {
        memorycommitresult mcr = committomemory();
        sharedpreferencesimpl.this.enqueuediskwrite(
            mcr, null /* sync write on this thread okay */);
        try {
            mcr.writtentodisklatch.await();
        } catch (interruptedexception e) {
            return false;
        }
        notifylisteners(mcr);
        return mcr.writetodiskresult;
}  

以上就是commit的代码,最终返回执行成功或者失败,具体细节我们先分析下一个对象–memorycommitresult

代码2:
private static class memorycommitresult {
    public long memorystategeneration;
    public list keysmodified;  // may be null
    public set listeners;  // may be null
    public map maptowritetodisk;
    public final countdownlatch writtentodisklatch = new countdownlatch(1);
    public volatile boolean writetodiskresult = false;

    public void setdiskwriteresult(boolean result) {
        writetodiskresult = result;
        writtentodisklatch.countdown();
    }
}  

解释下这个类的具体作用,这个类记录着内存中key-value的变化并将这种变化告诉listener。memorystategeneration实际上是一种xml配置版本记录,中存在着mcurrentmemorystategeneration和mdiskstategeneration,他们的类型均为long,分别记录了一个数值,这个数值表示key-value是否已经发生变化,在commit的时候是否需要写入xml文件。mdiskstategeneration表示上一次执行commit后xml配置文件版本,mcurrentmemorystategeneration和memorystategeneration表示当前xml配置文件的版本,在将key-value写入xml配置文件时,只有memorystategeneration大于mdiskstategeneration时,系统才会将key-value写入xml配置文件;keysmodified表示发生变化的key,发生变化可能是新添加也可能是修改了key对应的value。listeners表示监听sharedpreference上key变化的监听器;maptowritetodisk是需要写入xml配置文件的key-value集合;writetodiskresult表示写入xml配置文件的结果;writtentodisklatch,在commit将key-value写入xml配置文件时,系统使用writtentodisklatch让程序阻塞,直到commit写入完成。

介绍完memorycommitresult,committomemory()方法,committomemory()方法代码其实很好分析,主要功能就是记录当前需要写入配置文件的key-value,并将需要写入xml配置文件的key-value全部存储在maptowritetodisk,同时收集value发生变化的key。maptowritetodisk初始值为mmap(mmap可见sharedpreferences的具体实现1中的介绍)。系统会遍历mmodified(mmodified可见sharedpreferences的具体实现1中的介绍),并通过一定的机制将需要写入xml配置文件的key-value值添加到maptowritetodisk中,同时添加到keysmodified中;同时修改memorystategeneration。

enqueuediskwrite中执行的核心代码是writetofile(mcr, isfromsynccommit)方法,接下来我们主要分析下这部分的代码。
在分析这段代码之前,我们需要了解系统在写入配置文件时,有一个保护机制,为原来的配置文件生成一份备份文件,写入成功后删除备份文件,写入失败后从备份文件中恢复。看下写入文件的代码:

try {
        fileoutputstream str = createfileoutputstream(mfile);
        ....
        xmlutils.writemapxml(mcr.maptowritetodisk, str);
        ....
    }  

我注释了其他代码,只保留了最核心的代码,可以发现最核心的部分就是将需要写入配置文件的xml写入对应的文件输出流。