Пожарная машина Нью-Йорка, начало XX века.

Пожарная машина Нью-Йорка, начало XX века.

Это серия статей от Mark Murphy из CommonsWare, широко известного на stackoverflow,  а так же автора книг “The Busy Coder’s Guide to Android Development”, “Android’s Architecture Components”.

Storage Situation: Internal Storage

Существует много путаницы в отношении модели хранения Android. Эта путаница значительно ухудшилась с изменениями Android 4.4 в этой storage model, и с тех пор она не улучшилась. Есть бесчисленное множество вопросов на Stack Overflow и тому подобных, где люди явно не совсем разбираются в различных моделях хранения Android.

То, что пользователи считают «внутренним хранилищем»

В зависимости от модели вашего устройства пользователи в конечном итоге придут в «Настройки»> «Хранение на своем устройстве» или в эквивалентном месте, и могут видеть экран, который описывает «Внутреннее хранилище»:

internal-storage

И это будет так. Пользователь думает, что вся встроенная флешка — это «внутреннее хранилище» (Internal Storage). К счастью, Google начал менять этот термин с Android 8.0, перейдя к общему «хранилищу», а не «внутреннему хранилищу».

Тем не менее, пользователи могут по-прежнему видеть «внутреннее хранилище» в таких местах, как окно проводника в Windows, когда их устройство подключено через USB.

Что Google считает «внутренним хранилищем» ?

Увы, это не то, что Android SDK считает «внутренним хранилищем», что приводит к некоторой путанице. Если вы читали документацию на Android по внутреннему хранилищу, то это описание … как минимум туманное:

Вы можете сохранять файлы непосредственно во внутренней памяти устройства. По умолчанию файлы, сохраненные во внутреннем хранилище, являются приватными для вашего приложения, и другие приложения не могут получить к ним доступ (также каки пользователь). Когда пользователь удаляет приложение, эти файлы удаляются.

По правде говоря, Android SDK определяет «внутреннее хранилище» как особый каталог, уникальный для вашего приложения, где ваше приложение может размещать файлы. Как было предложено в документах, эти файлы по умолчанию предназначены для чтения и записи для вашего приложения и запрещены для любого другого приложения (исключение: пользователи, работающие с файловыми менеджерами с привилегиями суперпользователя на rooted устройствах могут получить доступ ко всему).

В Context есть несколько базовых методов, которые предоставляют вам доступ к внутреннему хранилищу, в том числе:

  • getCacheDir()
  • getDir()
  • getDatabasePath()
  • getFilesDir()
  • openFileInput()
  • openFileOutput()
Читать ещё :   Руководство по архитектуре приложений. Часть 2

Другие методы будут опираться на них, такие как openOrCreateDatabase(). Другие классы также будут полагаться на них, такие как SQLiteOpenHelper и SharedPreferences.

Где хранится внутреннее хранилище … Иногда

Если вы просматриваете различные сообщения в блогах, ответы на StackOverflow и книги, выпущенные в 2012 году или ранее, вам сообщается, что «внутреннее хранилище» вашего приложения находится по адресу:

/data/data/your.application.package.name

Внутри будут некоторые каталоги, автоматически созданные Android, поскольку вы используете некоторые из методов Context. Например, getFilesDir() возвращает объект File, указывающий на каталог  files/  во внутреннем хранилище вашего приложения.

Где хранится внутреннее хранилище … Остальное время

Однако это не всегда, где находится внутреннее хранилище вашего приложения. Для разработчиков есть одно правило, которое вы должны усвоить из этой серии сообщений в блоге, это:

NEVER HARDCODE PATHS

Что еще более важно, внутреннее хранилище не всегда находится в одном месте. Примечательно, что у нас есть понятие отдельных профилей пользователей (user profiles), начиная с Android 4.2 для планшетов и Android 5.0 для телефонов. Каждый пользователь получает свое собственное «внутреннее хранилище». Хотя вышеупомянутый каталог по-прежнему используется для основного пользователя, не гарантируется, что он же будет использоваться для вторичных учетных записей.

Исследуем внутреннее хранилище

Device File Explorer tool в Android Studio 3.0+ может просматривать все внутренние хранилища на эмуляторе, а также внутреннее хранилище отлаживаемых приложений на продакшн устройствах. Это должно обрабатывать большинство ваших сценариев:

files5

В командной строке вы можете использовать adb с опцией run-as

Например, чтобы загрузить базу данных из внутреннего хранилища основного пользователя на вашу машину для разработки, вы можете использовать:

adb shell ‘run-as your.application.package.name cp /data/data/your.application.package.name/databases/dbname.db /sdcard’

Обратите внимание, что:

  • Вам нужно будет изменить пункт назначения туда, где на вашем устройстве отображается внешнее хранилище (показано здесь как /sdcard/, которое не будет одинаковым на всех устройствах)
  • Возможно, вам придется использовать cat вместо cp на старых устройствах
  • После того, как файл будет находиться на внешнем хранилище, вы сможете использовать adb pull, чтобы загрузить его на свою машину разработки, или получить доступ к нему другими обычными способами (например, путем монтирования устройства в качестве диска на вашей машине разработки).

Ограничения внутреннего хранилища

На старых устройствах Android 1.x и 2.x внутреннее хранилище обычно находилось в выделенном разделе файловой системы, и этот раздел обычно был довольно крошечным. HTC Dream (a.k.a., T-Mobile G1), оригинальное Android-устройство, обладал огромным 70 МБ встроенной памяти для использования всеми приложениями (это не опечатка, в то время мы измеряли память в мегабайтах).

К тому времени, когда вышли 2.3 устройства, внутреннее хранилище могло быть размером 1 ГБ.

Android 3.0 изменил модель хранилища, так как внутреннее хранилище стало больше объемом. У устройств, которые рекламируют как имеющее 4 ГБ, 8 ГБ, 16 ГБ и т.д. пространства для хранения, обычно имелось все это (минус существующее содержимое) доступное для внутреннего хранилища. Мы рассмотрим, что изменилось в Android 3.0 и его влияние на модель хранилища в следующих постах про внешнее хранилище.

Для Android 1.x и 2.x внутреннее хранилище было действительно только для небольших файлов, и вам нужно было использовать внешнее хранилище для всего остального. Android 3.0+ означает, что для большинства устройств и большинства пользователей внутреннее хранилище отлично подходит для файлов, которые не предназначены для обычного использования другими приложениями или доступны пользователю независимо от вашего приложения. Однако некоторые опытные пользователи обнаруживают, что даже on-board flash недостаточна для того, что они хотят хранить, поэтому они переходят на съемные хранилища.

Продолжение следует…

Читать ещё :   Работа с Lifecycles с помощью Lifecycle-Aware компонент. Часть 1

Читать еще