笔记——安卓存储知识(十)

《个人平时笔记,看到的同学欢迎指正错误》

1、存储相关详解知识

安卓起初早年是有内置SD卡和可扩展插拔TF卡区分的,但是近年手机内置SD卡的高内存导致越来越少的手机支持TF卡(外置SD卡)扩展了。并且现在默认都是将文件优先存储于内置SD卡中。

以下项目app包名:com.fivefloor.bo.myview

(1)、内存(RAM)

内存与PC的内存是一样的,是用来运行程序,不能用来永久存储数据,手机一旦关机,在内存中的所有数据都将会丢失,内存也是现在人类制造的所有电子设备所必需拥有的。安卓中的运行时内存RAM,每个app一般分配16M或24M或者通过系统底层设置可以更改自定义。

(2)、内部存储(ROM)

就是就相当于是PC中的硬盘的私有存储角色。用于存储Andoid设备的操作系统和应用程序的存储介质,Android设备中的Android系统和应用程序(APK文件)都是存在内部存储区的。例如手机的/system/目录、/data/目录等。data文件夹就是我们常说的内部存储区,当我们打开data文件夹之后(没有root权限的话,我们也没法操作内部存储空间,不能打开该文件夹)。通过context.getCacheDir()、context.getFilesDir()等不带External字段获取的文件路径,如:/data/data/com.fivefloor.bo.myview/cache

(3)、外部存储区(ROM)

相当于PC中的硬盘、U盘或者移动硬盘。外部存储一般就是我们看到的storage文件夹,当然也有可能是mnt文件夹,这个不同厂家有可能不一样。storage或mnt文件夹即为外部存储区,外部存储中的文件是可以被用户或者其他应用程序修改的,有两种类型的文件(或者目录):

>1.公共文件Public files:文件是可以被自由访问,且文件的数据对其他应用或者用户来说都是有意义的,当应用被卸载之后,其卸载前创建的文件仍然保留。比如camera应用,生成的照片大家都能访问,而且camera不在了,照片仍然在。公有目录有九大类,比如DCIM、DOWNLOAD、PICTURES等这种系统为我们创建的文件夹。如:/storage/emulated/0/Pictures >2.私有文件Private files:其实由于是外部存储的原因即使是这种类型的文件也能被其他程序访问,只不过一个应用私有的文件对其他应用其实是没有访问价值的(恶意程序除外)。外部存储上,应用私有文件的价值在于卸载之后,这些文件也会被删除。类似于内部存储,只是和内部储存不同的是这个部分可以给用户和其他应用访问。所以才叫外部储存的私有部分嘛。私有目录就是Android这个文件夹路径下的。如:/storage/emulated/0/Android/data/com.fivefloor.bo.myview/cache >3.外部TF卡也是属于外部存储的,而要注意外置TF卡(外置SD卡)一般为:/storage/sdcard1或者/storage/sdcard2或 mnt/ext_sdcard,有些手机可以扩展多张TF卡。

注意内部存储不是内存。从用户角度来说SD卡有内置SD卡和外置TF卡之分,通过Environment或者Context获取的都是手机自带的内置SD卡路径,类似storage/emulated/0/加后缀。内部存储和外部存储并不是按是否存储于SD卡来区分的,内部存储是在data文件下,外部存储是在storage或者mnt文件夹下,这就是区别。内部存储,我们称为InternalStorage,外部存储我们称为ExternalStorage。内部存储和外部存储的私有文件(也就是app包名下的)都是属于该app的,app卸载了他们也就跟着删除了。

sd.png

如果按照路径的特征,我们又可以将文件存储的路径分为两大类,一类是路径中含有包名的,一类是路径中不含有包名的,含有包名的路径,因为和某个App有关,所以对这些文件夹的访问都是调用Context里边的方法;而不含有包名的路径,和某一个App无关,我们可以通过Environment中的方法来访问,如:九大共有目录。如下图:

sdw.png

/** * 获取外置TF卡路径/storage/sdcard1/或/storage/0F1C-240A/等 * * @param mContext * @return */ public static String getExtendedSDMemoryPath(Context mContext) { //ECOENDARY_STORAGE这个值,代表是第二储存,即为外置可移动SD卡。EXTERNAL_STORAGE则对应的是手机内部的存储。 StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); Class<?> storageVolumeClazz = null; try { storageVolumeClazz = Class.forName("android.os.storage.StorageVolume"); Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList"); Method getPath = storageVolumeClazz.getMethod("getPath"); Method isRemovable = storageVolumeClazz.getMethod("isRemovable"); Object result = getVolumeList.invoke(mStorageManager); final int length = Array.getLength(result); for (int i = 0; i < length; i++) { Object storageVolumeElement = Array.get(result, i); String path = (String) getPath.invoke(storageVolumeElement); boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement); if (removable) { return path + File.separator; } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null;}

2、SQLite是一个轻量级的、嵌入式的关系型数据库,它遵守ACID的关联式数据库管理系统,是主要针对于嵌入式设备专门设计的数据库。SQLite支持最大2TB的存储空间,在Android中SQLite是受手机系统存储空间(ROM)也就是机身内存大小限制的,不包括外置SD卡空间。所有app程序共用一个SQLite数据库,但是数据库表不同多个app不共用,这个需要注意理清。

优秀的数据库框架:GreenDao、OrmLite、Litepal等

3、android应用程序(进程)内存(RAM)一般限制在16M,也有的是24M(早期的Android系统G1,就是只有16M),根据开发人员的定义也可以扩展;进程是作为资源分配的基本单位,可以创建多进程来获取系统分配更多的资源内存,通过给四大组件指定android:process属性,我们可以轻易地开启多进程模式。Android为不同类型的进程分配了不同的内存使用上限,如果程序在运行过程中出现了内存泄漏的而造成应用进程使用的内存超过了这个上限,则会被系统视为内存泄漏,从而被kill掉。对于我们已经不需要使用的对象,我们可以把它设置为null,这样当GC运行的时候,就会遍历到你这个对象已经没有引用,会自动把该对象占用的内存回收。我们没法像C++那样马上释放不需要的内存,但是我们可以主动告诉系统,哪些内存可以回收了。也可以巧妙的运用弱引用和弱引用。

4、Java SE2开始,就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决定某些对象的生命周期;第二是有利于JVM进行垃圾回收。http://www.cnblogs.com/dolphin0520/p/3784171.html

>1.软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

importjava.lang.ref.SoftReference; publicclassMain {     publicstaticvoidmain(String[] args) {         SoftReference<String> sr = newSoftReference<String>(newString("hello"));         System.out.println(sr.get());     } }

>2.强引用就是指在程序代码之中普遍存在的,如我们常定义和实例化:String a="123";只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

>3.弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。

importjava.lang.ref.WeakReference; publicclassMain {     publicstaticvoidmain(String[] args) {         WeakReference<String> sr = newWeakReference<String>(newString("hello"));         System.out.println(sr.get());         System.gc();                //通知JVM的gc进行垃圾回收         System.out.println(sr.get());     } }

>4.虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

importjava.lang.ref.PhantomReference; importjava.lang.ref.ReferenceQueue; publicclassMain {     publicstaticvoidmain(String[] args) {         ReferenceQueue<String> queue = newReferenceQueue<String>();         PhantomReference<String> pr = newPhantomReference<String>(newString("hello"), queue);         System.out.println(pr.get());     } }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券