十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
SharedPreferences使用:
创新互联公司是专业的水城网站建设公司,水城接单;提供成都做网站、网站建设、外贸营销网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行水城网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
SharedPreferencesImpl#EditorImpl.java 中最终执行了apply()函数:
创建一个awaitCommit的Runnable任务并将其加入到QueuedWork中,该任务内部直接调用了CountDownLatch.await()方法,即直接在UI线程执行等待操作,那么我们看QueuedWork中何时执行这个任务。
QueuedWork.java:
waitToFinish()方法会尝试从Runnable任务队列中取任务,如果有的话直接取出并执行,我们看看哪里调用了waitToFinish():
ActivityThread.java
可以看到在ActivityThread中handleStopActivity、handleStopService方法中都会调用waitToFinish()方法,即在Activity的onStop()中、Service的onStop()中都会先同步等待写入任务完成才会继续执行。
所以apply()虽然是异步写入磁盘,但是如果此时执行到Activity/Service的onStop(),依然可能会阻塞UI线程导致ANR。
Jetpack DataStore 是一种改进的数据存储解决方案,允许您使用 协议缓冲区 存储键值对或类型化对象。
DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据。并且可以对SP数据进行迁移,旨在取代SP。如果正在使用 SharedPreferences 存储数据,请考虑迁移到 DataStore。
Jetpack DataStore 有两种实现方式:
1.添加依赖项:
2.构建Preferences DataStore:
当我们构建后,会在 /data/data/package name/files/ 下创建名为 preferences_dataStore 的文件如下:
1.构建Preferences DataStore
2.存储的实体类:
3.数据存储/获取:
Activity中:
ViewModel中:
Repository类中:
SP迁移至Preferences DataStore
如果想将项目的SP进行迁移,只需要在Preferences DataStore在构建时配置参数3,如下:
这样构建完成时,SP中的内容也会迁移到Preferences DataStore中了,注意迁移是一次性的,即执行迁移后,SP文件会被删除.
MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。
1.添加依赖:
2.Application的onCreate方法中初始化
3.数据存储/获取:
github地址:
在使用File存储App数据时,我们需要了解Android系统的存储系统。Android的存储分为内部存储和外部存储。
由于Android系统的厂商比较多,对于外部存储目录的定义有所不同,可能在根目录下的mnt,sdcard和storage下。以storage为例,打开emulated/0目录,外部存储目录就出现了。虽然可以通过多种路径打开外部存储文件,但是最终他们的路径是相同的:
mnt:
storage:
sdcard:
外部存储目录下包含两大类:公有目录和私有目录
私有目录:
对比下来External有以下几点优点:
缺点:
内部存储与外部存储权限申请对比如下:
首先我们要获取外部存储目标文件的路径:
然后确定自己需要创建的文件名,结合上面的到的路径,创建一个File对象:
Android系统默认数据清理的路径是,内部存储目录中相应的cache文件夹中的文件和外部存储中相应的cache文件夹中的文件。
你的app的internal storage 目录是以你的app的包名作为标识存放在Android文件系统的特定目录下[data/data/com.example.xx]。 从技术上讲,如果你设置文件为可读的,那么其他app就可以读取你的internal文件。然而,其他app需要知道你的包名与文件名。若是你没有设置为可读或者可写,其他app是没有办法读写的。因此只要你使用MODE_PRIVATE ,那么这些文件就不可能被其他app所访问。
另外记住一点,内部存储在你的APP卸载的时候,会一块被删除,因此,我们可以在cache目录里面放置我们的图片缓存,而且cache与files的差别在于,如果手机的内部存储空间不够了,会自行选择cache目录进行删除,因此,不要把重要的文件放在cache文件里面,可以放置在files里面,因为这个文件只有在APP被卸载的时候才会被删除。还有要注意的一点是,如果应用程序是更新操作,内部存储不会被删除,区别于被用户手动卸载。
不管你是使用 getExternalStoragePublicDirectory() 来存储可以共享的文件,还是使用 getExternalFilesDir() 来储存那些对于你的app来说是私有的文件,有一点很重要,那就是你要使用那些类似DIRECTORY_PICTURES 的API的常量。那些目录类型参数可以确保那些文件被系统正确的对待。例如,那些以DIRECTORY_RINGTONES 类型保存的文件就会被系统的media scanner认为是ringtone而不是音乐。
在开发中,不建议往内部存储中写太多的数据,毕竟空间有限。外部存储在使用的时候最好能够将文件存放在私有目录下,这样有利于系统维护,也避免用户的反感。
彻底理解android中的内部存储与外部存储
Android存储挖坑记
缓存文件可以放在哪里?它们各自的特点是什么
在平常使用Android手机的时候,我们都知道,几乎每一个app都在/data/data/相应的包名的文件夹下保存数据。那这些数据怎么进行保存的呢?在这里,将简单的介绍一下。
Context类中有一个openFileOutPut方法,这个方法可以将我们的数据保存在data目录下的文件里面。
openFileOutput(String name, int mode)方法中带两个参数,第一个参数是文件名,这里只能写文件的名字,不能包含路径,因为所有的数据都保存在/data/data/应用包名/files/目录下;第二个参数是文件的操作模式,有MDOE_PRIVATE,MODE_APPEND,MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE。
其中MODE_PRIVATE模式的是默认的操作模式,每一次写入的内容时,都会覆盖前面的内容;MODE_APPEND模式表示的是每次写入的内容追加在前面的后面;MODE_WORLD_READABLE表示的是其他应用程序可以对该文件进行写的操作;MODE_WORLD_WRITEABLE表示的是其他应用程序可以对该文件进行读的操作。不过在后面的两种模式过于危险,google已经在Android 4.2中废弃了。
openFileOutput()方法返回的是一个FileOutPutStream的对象,得到了这个对象,就可以使用Java的IO流来对文件的使用了。
点击保存过后,就会把我们的数据保存在data目录下。
如果我们想要查看的话,就可以在Android studio(我是2.3.2的版本)中找到Tools-Android-Android Device Monitor
再打开/data/data/应用包名/files/,发现有一个文件,就是我们之前创建的一个文件。
我们可以点击右上角的图标进行相应的导出工作,对相应的文件进行导出操作。
在Context类中,与openFileOutput方法对应的是openFileInput方法,用户从data目录读取相应的数据。这个方法相较于openFileOutput方法简单一些。
效果示意图: