永久化存储是日常开发中常用的知识点,除了用数据库存储,很多开发者会使用SharedPreferences进行永久化存储,因此SharedPreferences也是一个考点,面试官可能会问:
- SharedPreference是线程安全的吗?⭐⭐⭐
- SharedPreference的apply和commit的区别?commit 一定会在主线程操作嘛?⭐⭐⭐⭐⭐
- SharedPreferences 是如何初始化的,它会阻塞主线程吗?⭐⭐⭐
- 每次获取 SP 对象真的会很慢吗?⭐⭐⭐
- 在使用时需要注意哪些问题,以及有什么优化点呢?⭐⭐⭐⭐
看完以下的解析,一定可以让面试官眼前一亮。
1、SharedPreferences 是什么?怎么用?
从文章开头就知道SharedPreferences是Android用于永久性存储的一种方式,顺便复习下Android的永久性存储方式有哪些:
- File
- SharedPreferences
- SQlite
- 网络
- ContentProvider
SharedPreferences是基于key-value 键值对生成的一个xml文件,保存在/data/data/packageName/shared_prefs目录下,适合保存少量数据,且数据格式相对简单。
SharedPreferences sharedPreferences = context.getSharedPreferences(“xurui”, Context.MODE_PRIVATE); //1
SharedPreferences.Editor editor = sharedPreferences.edit(); //2
editor.putString("key", "value"); //3
editor.apply(); //4
//使用
String value = sharedPreferences.getString("key", "defaultValue"); //5
SharedPreferences本身是一个接口,可以通过getSharedPreferences()获取实例,原型是:
SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode);
其中name是最终生成的xml文件的文件名,mode代表不同的存储方式,查看源码有:
@IntDef(flag = true, prefix = { "MODE_" }, value = {
MODE_PRIVATE,
MODE_WORLD_READABLE,
MODE_WORLD_WRITEABLE,
MODE_MULTI_PROCESS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PreferencesMode {}
mode分成以下5种类型:
- MODE_PRIVATE:表示该 SharedPreferences数据只能被本应用读写,或者有相同用户ID的应用读写;
- MODE_WORLD_READABLE:全局读,允许所有其他应用程序对创建的文件具有读访问权限,该模式官方强烈建议不使用,因为会造成安全问题;
- MODE_WORLD_WRITEABLE:全局写,允许所有其他应用程序对创建的文件有写访问权限,官方同样建议不使用;
- MODE_MULTI_PROCESS:可以实现多进程访问SharedPreferences数据的问题,但是这种方式的多进程共享数据可能会出现数据不一致的问题,也不可靠,现在也不使用了;
- MODE_APPED:该模式不在规定的PreferencesMode模式里,但也可以使用,如果文件存在且对应的key也存在,则可以在对应的value数值追加新的内容,不同于MODE_PRIVATE,MODE_PRIVATE会把旧的内容覆盖掉。
接着,获取到的SharedPreferences实例本身仅支持获取数据,如果需要修改或者储存,需要通过SharedPreferences.Editor来实现,同样Editor也是接口,可以通过sharedPreferences.edit()获取实例,并通过putString修改内容,最后执行apply()即可(apply()下面会分析)。如此我们就完成了一对key-value 键值对的存放,到/data/data/packageName/shared_prefs下就可以找到一个叫“xurui.xml"的文件,里面就存放着刚添加的键值对。
2. SharedPreferences存储安全风险源于?
答:(1)开发者在创建文件时没有正确的选取合适的创建模式(MODE_PRIVATE、MODE_WORLD_READABLE以及MODE_WORLD_WRITEABLE)进行权限控制;
(2)开发者过度依赖Android系统内部存储安全机制,将用户信息、密码等敏感重要的信息明文存储在Shared Preferences文件中,导致攻击者可通过root手机来查看敏感信息。
3. 每次调用getSharedPreferences时都会创建一个SharedPreferences对象吗?这个对象具体是哪个类对象?
答:不是,只要name相同,就会返回同一个SharedPreferencesImpl对象,packagePrefs存放文件name与SharedPreferencesImpl键值对,sSharedPrefs存放包名与ArrayMap键值对。注意sSharedPrefs是static变量,也就是一个类只有一个实例,因此每次getSharedPreferences其实拿到的都是同一个SharedPreferences对象。
4. 在UI线程中调用getXXX有可能导致ANR吗?
答:有可能的,getXXX之前,会给当前线程加锁,如果sp文件特别大,查询非常耗时的时候,有可能ANR。
5. 为什么SharedPreferences只适合用来存放少量数据,为什么不能把SharedPreferences对应的xml文件当成普通文件一样存放大量的数据?
答:其实这个和第三个问题没什么区别,因为SharedPreferences是整个文件都加载到内存中,文件太大了会对内存造成压力。
6. commit和apply有什么区别?(网易互娱面试原题)
答:①commit和apply虽然都是原子性操作,但是原子的操作不同,commit是原子提交到数据库,所以从提交数据到存在Disk中都是同步过程,中间不可打断。
②而apply方法的原子操作是原子提交到内存中,而非数据库,所以在提交到内存中时不可打断,之后再异步提交数据到数据库中,因此也不会有相应的返回值。
③所有commit提交是同步过程,效率会比apply异步提交的速度慢,但是apply没有返回值,永远无法知道存储是否失败。
④commit发生在UI线程,而apply发生在工作线程。
⑤在不关心提交结果是否成功的情况下,优先考虑apply方法。
(commit()方法会同步地将偏好值(Preference)直接写入持久化存储设备,而apply()方法会立即把修改内容提交到SharedPreferences内容缓存中,然后开始异步的将修改提交到存储设备上,在这个过程中,开发者不会察觉到任何错误问题)
7. apply一定安全吗?
答:不一定。虽然apply使写入文件操作发生在工作线程中,这样防止IO操作阻塞UI线程。假如我们apply非常多的任务,而线程池队列是串行执行,当我们关闭Activity时:会检查线程池队列中任务是否已经全部执行完成,否则一直等到全部执行完成。如果此时等待超过5s,会造成程序崩溃。
8. SharedPreferences每次写入时是增量写入吗?
答:不是,SharedPreferences每次写入都是整个文件重新写入,不是增量写入。SharedPreferences在写入时会把之前的xml文件改名成一个备份文件,然后再将要写入的数据写入到一个新的文件中,如果这个过程执行成功的话,就会把备份文件删除。由此可见每次即使只是添加一个键值对,也会重新写入整个文件的数据,这也说明SharedPreferences只适合保存少量数据,文件太大有性能问题。
由于面试内容比较多,篇幅有限,资料已经被整理成了PDF文档,有需要2023年Android中高级最全面试真题答案 完整文档的可
目录
第一章 Java方面
●Java基础部分
●Java集合
●Java多线程
●Java虚拟机
第二章 Android方面
●Android四大组件相关
●Android异步任务和消息机制
●Android UI绘制相关
●Android性能调优相关
●Android中的IPC
●Android系统SDK相关
●第三方框架分析
●综合技术
●数据结构方面
●设计模式
●计算机网络方面
●Kotlin方面
第三章 音视频开发高频面试题
●为什么巨大的原始视频可以编码成很小的视频呢?这其中的技术是什么呢?
●怎么做到直播秒开优化?
●直方图在图像处理里面最重要的作用是什么?
●数字图像滤波有哪些方法?
●图像可以提取的特征有哪些?
●衡量图像重建好坏的标准有哪些?怎样计算?
第四章 Flutter高频面试题
●Dart部分
●Flutter部分
第五章 算法高频面试题
●如何高效寻找素数
●如何运用二分查找算法
●如何高效解决雨水问题
●如何去除有序数组的重复元素
●如何高效进行模幂运算
●如何寻找最长回文子串
第六章 Andrio Framework方面
●系统启动流程面试题解析
●Binder面试题解析
●Handler面试题解析
●AMS面试题解析
第七章 企业常见174道面试题
●SD卡
●Android的数据存储方式
●Broadcast Receiver
●sp频繁操作会有什么后果?sp能存多少数据?
●dvm与jvm的区别
●ART
●Activity的生命周期
●Application能不能启动Activity
●…