Вътрешната памет на приложението е отделено пространство на устройството, достъпно само за конкретното приложение чрез изолирано хранилище. Според Android Developers, 2026, всяко приложение получава собствена sandbox директория, до която другите приложения нямат пряк достъп. Този подход защитава данните от неоторизирано четене и осигурява стабилна работа в многозадачна среда на мобилните устройства.
Основни точки
Context.getFilesDir(), getCacheDir() и getDataDir() за достъп до вътрешната паметNSDocumentDirectory и NSCachesDirectory в Sandbox контейнера на приложениетоВътрешната памет на приложението е изолирана директория, която операционната система отделя на всяко приложение при инсталирането му. Други приложения и потребителят нямат достъп до тази директория чрез стандартни файлови мениджъри. Системата гарантира, че данните в тази директория ще бъдат напълно изтрити при деинсталиране на приложението. Този подход съставлява основата на модела за сигурност на мобилните операционни системи, предотвратявайки изтичане на поверителна информация между програми.
За разлика от външното хранилище (SD карта), вътрешната памет винаги е достъпна и не изисква проверка за наличие на носител. Скоростта на четене и запис в NAND флаш паметта на съвременните устройства достига 800–900 MB/s последователно четене и 200–300 MB/s последователен запис, което е сравнимо с SATA SSD. Размерът на отделената област зависи от общия капацитет на устройството и политиката на производителя: на устройства с 64 GB флаш памет приложението получава 16–64 MB начално пространство с възможност за разширяване при необходимост.
Архитектурата на вътрешното хранилище се различава на Android и iOS. На Android всяко приложение получава директория /data/data/<package_name>/, вътре в която системата създава поддиректории files/, cache/ и databases/. На iOS приложението работи в Sandbox контейнер с директории Documents/, Library/ и tmp/, всяка от които има свое предназначение и политика за архивиране.
Разработчиците разполагат с няколко начина за запазване на данни във вътрешната памет на приложението. Всеки метод решава определена задача и е подходящ за определен тип данни. Изборът на правилния начин пряко влияе върху производителността на приложението, удобството за разработка и сигурността на потребителските данни.
Най-ниското ниво е директният запис на файлове в директорията files. Приложението може да създава всякакви файлове и директории вътре в своята пясъчна кутия. Този метод е подходящ за съхранение на медийни файлове, потребителски документи и всякакви бинарни данни, които не изискват структурирана организация. На Android достъпът до директорията се осъществява чрез извикване на Context.getFilesDir(), което връща абсолютния път до директорията с файлове на приложението. На iOS аналогична функция изпълнява NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).
За съхранение на двойки ключ-стойност Android предлага SharedPreferences и по-модерния DataStore, базиран на Kotlin корутини и протокол protobuf. SharedPreferences съхранява данни в XML файл в директорията /data/data/<package>/shared_prefs/. Въпреки лесната употреба, SharedPreferences има недостатъци: синхронният запис може да причини закъснения в UI нишката, а липсата на типова безопасност повишава риска от грешки. DataStore решава тези проблеми, предоставяйки асинхронен API, базиран на Flow, и пълна поддръжка на типове чрез protobuf схеми.
За структурирани данни с релационни връзки оптималният избор е SQLite или обвивката Room. Базата данни се съхранява в един файл в директорията databases/ и поддържа пълен SQL синтаксис. Room е официалната библиотека Jetpack, която предоставя типобезопасен API, автоматична миграция на схема и поддръжка на корутини. Размерът на базата данни може да достигне няколко гигабайта без съществена загуба на производителност при правилно индексиране. SQLite на мобилни устройства обработва до 50 000 записващи операции в секунда на съвременен флагмански процесор.
За съхранение на поверителни данни, като токени за удостоверяване и ключове за криптиране, Android предоставя EncryptedSharedPreferences. Тази обвивка над стандартните SharedPreferences автоматично криптира ключовете и стойностите, използвайки AES256-GCM-None. Криптирането се извършва на файлово ниво преди запис на диска, така че дори при физически достъп до устройството нападателят не може да прочете съдържанието. EncryptedSharedPreferences е част от библиотеката AndroidX Security, която включва също EncryptedFile за криптиране на цели файлове.
Android SDK предоставя набор от методи за работа с вътрешната памет чрез класа Context. Всеки метод връща пътя до определена системна директория в пясъчната кутия на приложението. Нека разгледаме основните операции за запис и четене на файлове с пример на Kotlin.
Основният метод за получаване на пътя до вътрешната файлова директория е context.filesDir. Той връща обект File, указващ към директорията /data/data/<package>/files/. При първото обръщение системата създава автоматично всички необходими родителски директории. Размерът на файловете във вътрешната памет не е изрично ограничен, но общият обем данни не трябва да надвишава наличното пространство на дяла /data, което обикновено съставлява 60–80% от общия обем флаш памет на устройството.
val context = getApplicationContext()
val file = File(context.filesDir, "notes.txt")
file.writeText("Съдържание на бележката")
val content = file.readText()
println("Прочетено: $content")
Методите writeText и readText са extension функции на стандартната библиотека на Kotlin. Те автоматично управляват отварянето и затварянето на потоци, което изключва изтичане на памет. За бинарни данни използвайте writeBytes и readBytes, които не изискват кодиране и работят с масиви ByteArray. При работа с големи файлове се препоръчва използването на буферирани потоци: BufferedReader и BufferedWriter за текст, BufferedInputStream и BufferedOutputStream за бинарни данни.
За организиране на файловете в йерархия създавайте поддиректории във filesDir. Това помага да структурирате данните по тип: изображения, документи, експортни файлове. Методът mkdirs() създава всички липсващи директории в пътя, включително вложените. Уверете се, че операцията по създаване е успешна — методът връща true само при създаване на нови директории. Грешка при създаване най-често е свързана с липса на място на дяла /data или изчерпване на иноди на файловата система.
val imagesDir = File(context.filesDir, "images")
if (imagesDir.mkdirs()) {
println("Директорията е създадена")
}
val imageFile = File(imagesDir, "photo.jpg")
imageFile.writeBytes(byteArray)
За проверка на наличното пространство преди запис на големи файлове използвайте File.getFreeSpace() или File.getUsableSpace(). Вторият метод връща броя байтове, достъпни за текущото приложение, като взема предвид квотите за сигурност — той е по-точен в контекста на много потребителски устройства. Ако наличното пространство е по-малко от очаквания размер на файла, покажете съобщение на потребителя и предложете да освободи място в настройките на устройството.
На iOS всяко приложение работи в изолиран Sandbox контейнер. Системата не предоставя API за излизане извън неговите граници без специални права. Основният инструмент за работа с файловата система е класът FileManager от Foundation framework. Sandbox контейнерът включва няколко стандартни директории, всяка със собствена политика за архивиране.
Директорията Documents е предназначена за потребителски данни, които трябва да се запазват между стартиранията на приложението и да се възстановяват от резервно копие. iOS автоматично включва тази директория в архивирането в iCloud и iTunes. Методът urls(for:in:) връща масив от URL адреси на заявената директория — първият елемент от масива е основният.
let fm = FileManager.default
let docs = fm.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let fileURL = docs.appendingPathComponent("data.plist")
try data.write(to: fileURL)
FileManager поддържа пълен набор от файлови операции: създаване, копиране, преместване, изтриване и преименуване. Всяка операция може да хвърли грешка, затова всички извиквания трябва да бъдат обвити в конструкция do-catch. Особено внимание обръщайте на изтриването на файлове — операцията е необратима и възстановяването на данни след removeItem(at:) е невъзможно без предварително резервно копие.
Не всички данни в Sandbox контейнера трябва да попадат в iCloud резервното копие. Например кешът на изтеглени изображения или временни файлове за обработка не е необходимо да се възстановяват — те ще бъдат създадени отново при следващото използване. За изключване на директория или файл от архивиране задайте атрибута isExcludedFromBackup на true. Apple препоръчва винаги да изключвате от архива данни, които могат да бъдат възстановени дистанционно, за да минимизирате обема на iCloud хранилището и да съкратите времето за възстановяване.
var cacheURL = fm.urls(
for: .cachesDirectory,
in: .userDomainMask
).first!
cacheURL.hasExcludedFromBackupKey = true
var values = URLResourceValues()
values.isExcludedFromBackup = true
try cacheURL.setResourceValues(values)
Всеки тип хранилище на мобилното устройство има свое предназначение и правила за използване. Разбирането на тези разлики помага на разработчика да избере правилното място за всеки тип данни. По-долу е представено сравнение на трите основни типа хранилища, достъпни за приложението.
| Характеристика | Internal Storage | Cache Directory | External Storage |
|---|---|---|---|
| Видимост за други приложения | Скрита | Скрита | Достъпна |
| Изтриване при деинсталиране | Пълно | Пълно | Зависи от местоположението |
| Архивиране | На Android — не, на iOS — да (Documents) | Не | Само при синхронизация |
| Достъпност без носител | Винаги | Винаги | Изисква SD карта |
| Риск от загуба на данни | Минимален | Висок | Среден |
| Препоръчителен размер на файлове | До 100 MB | До 50 MB | Всякакъв |
Вътрешната памет е оптимална за съхранение на конфигурации на приложението, файлове на базата данни и потребителски документи, които не трябва да бъдат достъпни за други програми. Кеш директорията е предназначена за временни файлове, които могат да бъдат пресъздадени при следващо използване: изтеглени изображения, API отговори, междинни данни за обработка. Външното хранилище е най-подходящо за големи медийни файлове (снимки, видеа, музика) и данни, които потребителят иска да споделя с други приложения чрез общ достъп.
Изборът на тип хранилище също влияе върху рейтинга на приложението в Google Play и App Store. Приложенията, които съхраняват големи обеми данни във вътрешната памет без почистване, получават отрицателни отзиви: потребителите се оплакват от липса на място. Според изследване на App Annie, 62% от потребителите изтриват приложение, ако то заема повече от 500 MB вътрешна памет на устройството без опция за почистване.
Правилното управление на вътрешната памет на приложението повишава производителността, сигурността и потребителското изживяване. Следващите препоръки са базирани на официалната документация на Android и iOS, както и на практическия опит от разработката на приложения с милиони инсталации.
Отделно внимание трябва да се обърне на тестването на гранични случаи. Тествайте поведението на приложението при препълване на вътрешната памет, при внезапно прекъсване на запис (срив на приложението, обаждане) и при възстановяване от резервно копие на iOS. Във всеки от тези сценарии данните трябва да останат консистентни или да бъдат възстановени до последното стабилно състояние. Използвайте транзакционни файлове: записвайте данните във временен файл, след което атомарно го преименувайте в целевия. Това предотвратява четене на повредени данни при грешка в записа.
Не забравяйте за потребителския контрол. Предоставете в настройките на приложението опция за почистване на временни данни и показване на заетия обем вътрешна памет. Според Google Play Console, приложенията с такава функция получават 18% повече положителни отзиви в категорията "Производителност".
Често задавани въпроси
Всички данни от вътрешната памет на приложението се изтриват напълно. Операционната система гарантира липса на остатъчни файлове, включително бази данни, настройки и временни файлове. Данните на външното хранилище при това могат да се запазят.
Без root достъп до устройството други приложения не могат да четат файлове от Internal Storage на друго приложение. На Android за това се изискват привилегии на суперпотребител, а на iOS изолацията се осигурява на ниво ядро чрез Sandbox.
Няма изричен лимит, но общият обем е ограничен от свободното пространство на дяла /data. Препоръчва се да не надвишавате 100 MB на приложение — по-големи обеми е по-добре да се поставят на външно хранилище или в облака.
filesDir е предназначен за постоянни данни на приложението и не се изтрива от системата без необходимост. cacheDir е за временни файлове, които системата може да изтрие при недостиг на памет. Системата не гарантира запазването на cacheDir.
Директното копиране от Internal Storage на SD карта е забранено от политиката за сигурност. Използвайте MediaStore API на Android 10+ или SAF (Storage Access Framework) за създаване на копия на данни в общ достъп със съгласието на потребителя.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също