2013-05-15 3 views
19

У меня есть простое приложение, которое обеспечивает доступ и запись данных на внешнее хранилище. Все работает нормально, пока я не перейду в Настройки -> Приложения -> Информация о приложении и не очистите данные с помощью кнопки «Очистить данные», , после чего каждый звонок до getExternalCacheDir() начинает возвращать нуль.getExternalCacheDir() возвращает null после очистки данных

Я разрабатываю Nexus 7 под управлением Android 4.2.2.

Мои манифеста выглядит так:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.package" 
    android:versionCode="5" 
    android:versionName="1.3" 
    xmlns:tools="http://schemas.android.com/tools"> 

<uses-sdk 
    android:minSdkVersion="8" 
    android:targetSdkVersion="17" /> 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.INTERNET" /> 

<application 
... 

фрагмент кода, который не работает:

Log.d(TAG, "getExternalStorageState() = " + Environment.getExternalStorageState()); 
    Log.d(TAG, "getExternalCacheDir() = " + c.getExternalCacheDir()); 
    Log.d(TAG, "getExternalFilesDir(null) = " + c.getExternalFilesDir(null)); 
    Log.d(TAG, "getExternalFilesDir(Environment.DIRECTORY_MOVIES) = " + c.getExternalFilesDir(Environment.DIRECTORY_MOVIES)); 

LogCat после установки и выполняется приложение:

05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalStorageState() = mounted 
05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalCacheDir() =  /storage/emulated/0/Android/data/com.example.package/cache 
05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalFilesDir(null) = /storage/emulated/0/Android/data/com.example.package/files 
05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalFilesDir(Environment.DIRECTORY_MOVIES) = /storage/emulated/0/Android/data/com.example.package/files/Movies 

LogCat после очистки данных в настройках App Info:

05-15 11:27:57.848: DEBUG/HelperUtils(5859): getExternalStorageState() = mounted 
05-15 11:27:57.848: WARN/ContextImpl(5859): Unable to create external cache directory 
05-15 11:27:57.848: DEBUG/HelperUtils(5859): getExternalCacheDir() = null 
05-15 11:27:57.848: WARN/ContextImpl(5859): Unable to create external files directory 
05-15 11:27:57.848: DEBUG/HelperUtils(5859): getExternalFilesDir(null) = null 
05-15 11:27:57.848: WARN/ContextImpl(5859): Unable to create external files directory 
05-15 11:27:57.848: DEBUG/HelperUtils(5859): getExternalFilesDir(Environment.DIRECTORY_MOVIES) = null 
05-15 11:27:57.848: WARN/ContextImpl(5859): Unable to create external cache directory 

После очистки данных и выполнения приложения getExternalCacheDir() метод возвращает null, хотя Environment.getExternalStorageState() возвращает «установлен». Кто-нибудь знает, что может быть неправильным?

EDIT

С помощью Gjordis я узнал, что Очистить данные кнопка удаляет целое приложение во временный каталог:

storage/sdcard0/Android/data/com.example.app/cache в Android/data

, и я не смог создать он снова через getExternalCacheDir() или вручную (хотя я могу создавать другие каталоги под storage/sdcard0/Android/data/).

(Android/data/com.example.app создается снова после перезагрузки устройства, но это не решение, которое я ищу)

+0

Работает ли он после перезапуска вашего процесса (например, удалите приложение из списка недавних задач, а затем снова запустите приложение)? – CommonsWare

+0

@CommonsWare: Я попытался остановить приложение и удалить его из запущенных служб, но без каких-либо успехов. Я еще не могу снова создать каталог кэша в Android/data. Единственный способ заставить его работать снова - перезагрузить устройство - см. Отредактированный вопрос. – Andy

+2

Это похоже на ошибку. Увы, http://b.android.com сейчас не работает, поэтому я не могу подтвердить, подал ли кто-нибудь отчет об ошибке этого поведения. У вас есть полный проект, который служит в качестве воспроизводимого тестового примера, который вам может понравиться? (ZIP, указатель на репозиторий GitHub и т. Д.) – CommonsWare

ответ

6

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

getExternalFilesDir() возвращает каталог пространства для сохранения данных.

+1

Спасибо, господин Гьердис, вы правы, «Очистить данные» удаляет не только каталог кеша, но и весь каталог пакетов в Android/data. С этого момента я не могу снова создать этот каталог, и я вынужден перезагрузите устройство. Любые предложения? – Andy

+0

. Четкие данные обычно не используются для повторного использования. Только на uninstalls и неудачных конфигурациях и т. д. Вы уверены, что ваше приложение все еще не работает. Перезагрузка приложения должна воссоздать/data/.. in мой oppinion – Gjordis

-3

Если вы используете getExternal * Cache * Dir(), то для того, чтобы хранить TEMPORALY данные, которые могут быть очищены с помощью системы. Если другим приложениям, расположенным спереди на задней стороне, нужны ресурсы, система может очищать ваши данные, потому что ресурсы системы нужны. Если вы хотите сохранить данные настойчиво, используйте: File file = getExternalFilesDir (null); это внешняя память для хранения постоянных данных (например, виртуальная SD-карта).

+2

Проблема OP заключается не в том, что * файлы из каталога кэша * исчезают, но исчезновение самой * кеш-каталога *, что делает приложение неработоспособным, потому что hi не может повторно создать кэш для работы. – vbence

11

Я столкнулся и решил эту проблему.

Нажав кнопку «Очистить данные», приложение Android прекратит запуск вашего приложения и удалит всю папку приложения "mnt/sdcard/Android/data/your.package.name".

Однако у меня был отдельный процесс, который был запущен с Runtime.getRuntime().exec(), который все еще работал, и он писал эту папку. Это заставило папку застревать в заблокированном состоянии и вызвало тот же самый симптом, который вы описали, когда мое приложение вызвало getExternalCacheDir(). Запуск adb shell, а затем ls из папки/mnt/sdcard/Android/data показал, что папка была заблокирована процессом. Запуск ps показал, что мой другой процесс все еще работает.

Решение состояло в том, чтобы правильно убить другой процесс, который все еще записывался в папку приложения, предназначенную для приложения, перед вызовом getExternalCacheDir().

+0

Я подтверждаю , У меня было второе приложение, которое имело дескриптор открытого файла temp в каталоге кэша первого приложения, очистка данных для первого приложения вызвала t он застрял и не смог получить доступ к папке с кешем. Вышеуказанный ответ должен быть проголосован. :) – Arise

 Смежные вопросы

  • Нет связанных вопросов^_^