1. Android有哪些存储数据的方式?
Android系统提供了多种数据存储方式,以满足不同场景下的数据存储需求。主要包括以下几种:
-
SharedPreferences:
- 原理:基于键值对(key-value pair)的方式存储数据,数据以XML文件的形式保存在设备上。
- 特点:适合存储简单的配置信息,如用户偏好设置等。数据是私有的,只能被应用本身访问。
- 路径:通常保存在
/data/data/<package_name>/shared_prefs/
目录下。
-
文件存储(File):
- 原理:通过文件I/O的方式将数据存储在设备的存储介质中,可以是内部存储或外部存储(如SD卡)。
- 特点:适合存储大量数据,如图片、音频文件等。
- 路径:内部存储路径为
/data/data/<package_name>/files/
,外部存储路径则依赖于外部存储设备的挂载状态。
-
SQLite数据库:
- 原理:SQLite是一个轻量级的数据库,支持基本的SQL语法。Android为此数据库提供了SQLiteDatabase类,封装了操作数据库的API。
- 特点:适合存储结构化数据,如用户信息、应用数据等。
- 路径:通常保存在
/data/data/<package_name>/databases/
目录下。
-
Content Provider:
- 原理:允许不同应用之间共享数据,提供了一种跨应用的数据访问方式。
- 特点:适用于需要与其他应用共享数据的场景。
-
网络存储:
- 原理:将数据存储在服务器上,通过网络请求进行数据的读写操作。
- 特点:适用于需要跨设备同步数据的场景,如用户登录信息、应用更新等。
2. SharedPreference原理,commit与apply的区别是什么?使用时需要有哪些注意?
SharedPreference原理:
SharedPreferences是Android提供的一种轻量级的数据存储方式,基于键值对存储数据,数据以XML文件的形式保存在设备上。它提供了简单的API来读取和写入数据,并且支持数据持久化,即使应用关闭后数据依然存在。
commit与apply的区别:
-
commit:
- 同步操作:在当前线程中同步写入数据到XML文件。
- 线程安全:通过synchronized关键字保证线程安全。
- 性能:由于需要等待磁盘I/O操作完成,性能相对较慢。
-
apply:
- 异步操作:通过子线程异步写入数据到XML文件,不会阻塞当前线程。
- 线程不安全:由于数据写入是异步的,所以存在线程不安全的可能性。
- 性能:由于不需要等待磁盘I/O操作完成,性能较高。
使用时需要注意:
- 选择合适的方法:对于需要立即看到数据变更结果的场景,应使用commit方法;对于性能要求较高的场景,可以使用apply方法。
- 线程安全:在多线程环境下使用SharedPreferences时,需要注意线程安全问题。虽然commit方法是线程安全的,但在高并发场景下可能会成为性能瓶颈。
- 数据存储大小:由于SharedPreferences是基于XML文件实现的,并且所有数据都是一次性加载到内存中,因此不适合存储大量数据。
3. 如何判断一个APP在前台还是后台?
判断一个APP在前台还是后台,可以通过多种方式实现,包括但不限于以下几种:
-
通过Activity的生命周期:
- 当Activity的
onResume()
方法被调用时,可以认为应用处于前台。 - 当Activity的
onPause()
方法被调用时,可以认为应用即将进入后台或已经被其他应用覆盖。
- 当Activity的
-
使用ActivityManager:
- 通过
ActivityManager
的getRunningTasks()
或getRunningAppProcesses()
方法,可以获取当前运行的任务和进程信息。然后,可以遍历这些信息,判断自己的应用是否处于前台。但需要注意的是,getRunningTasks()
方法在Android 5.0(API级别21)及以上版本已被废弃,不再推荐使用。
- 通过
-
使用UsageStatsManager(Android 5.0及以上):
- 通过
UsageStatsManager
获取应用的使用统计信息,可以判断应用在过去一段时间内是否处于前台。但这种方法需要用户授权,且只能在Android 5.0及以上版本中使用。
- 通过
-
通过监听系统广播:
- 监听如屏幕开/关、用户活动等系统广播,可以间接判断应用是否处于前台。但这种方法不够准确,且可能受到系统权限和策略的限制。
4. 如何做应用保活?
应用保活是指在用户主动杀进程或系统基于当前内存不足状态而触发清理进程后,应用能够设法免于被杀或被杀后能立刻重生的手段。以下是一些常见的应用保活方案:
-
提升进程优先级:
- 通过监听系统广播(如屏幕开/关)或用户活动来启动服务或Activity,从而提升应用的进程优先级。
- 使用
START_STICKY
或START_REDELIVER_INTENT
等标志来启动Service,确保Service在被杀后能够自动重启。
-
使用双进程或多进程:
- 通过Native层或Java层实现多进程,相互监听对方进程状态。当一个进程被杀时,另一个进程可以重新启动被杀进程。
-
利用系统漏洞或特性:
- 这种方法通常不推荐使用,因为它可能违反Android系统的设计原则和安全策略。例如,通过修改系统文件或利用系统漏洞来绕过系统的进程管理策略。
-
优化应用性能:
- 通过减少内存占用、优化代码执行效率等方式来提升应用的性能和稳定性,从而降低被系统杀死的风险。
-
用户交互:
- 通过提醒用户不要清理后台应用或加入白名单等方式来增加应用的存活率。但这需要用户的配合和理解。
5. 一张图片100x100在内存中的大小?
一张图片在内存中的大小取决于其分辨率、颜色深度以及加载方式等多个因素。对于一张分辨率为100x100的图片,其内存占用大小可以通过以下方式计算:
- 颜色深度:在Android中,图片通常以ARGB_8888格式加载,即每个像素点占用4个字节(1字节=8位),分别表示Alpha(透明度)、Red(红色)、Green(绿色)和Blue(蓝色)通道。
- 内存占用:因此,一张100x100分辨率的图片在内存中的大小约为100x100x4 = 40000字节,即约39KB。但需要注意的是,这个计算结果是在未考虑图片压缩和加载方式(如BitmapFactory的加载选项)的情况下得出的。实际上,图片在内存中的占用大小可能会因这些因素而有所不同。
另外,如果图片是从资源文件中加载的(如放在drawable目录下),Android系统会根据设备的DPI值和资源目录的DPI值对图片进行缩放,这也会影响图片在内存中的实际占用大小。因此,在计算图片内存占用时,需要考虑这些因素的影响。