Создание временных файлов в Android с помощью NDK - PullRequest
18 голосов
/ 29 сентября 2011

В настоящее время я работаю над приложением для Android на основе C, NDK.Это приложение должно создавать временные файлы.В обычной системе Linux я бы использовал tmpfile, чтобы убедиться, что эти файлы правильно созданы во временном каталоге и очищены в конце процесса.

Однако мои исследования на различных устройствах Android, похоже, показывают, что

  • tmpfile всегда терпит неудачу;
  • отсутствует каталог /tmp; каталог
  • /data/local/tmp присутствует не во всех вариантах Android;
  • нет установленной переменной окружения TEMP;
  • mkstemp работает не лучше, чем tmpfile.

Теперь я уверенчто я мог бы взломать что-то вместе, но, увидев, что SDK предлагает context.getCacheDir и File.createTempFile для приложений Java, я надеюсь, что есть эквивалент на уровне C.

Кто-нибудь знает хороший надежный икросс-андроид метод для создания временного файла?

Ответы [ 4 ]

9 голосов
/ 05 октября 2011

Лучший способ, который мы нашли, это вызвать Context.getCacheDir при запуске, получить его путь с помощью getAbsolutePath, а затем вызвать функцию JNI для сохранения этого пути в глобальном.Любая функция, которая хочет создать временный файл, просто добавляет подходящее имя временного файла к этому пути.

Если вы действительно хотите извлечь его из JNI, другой альтернативой будет передача Context функции JNI.и использовать кучу вещей GetMethodID / CallObjectMethod для обратного вызова в Java к getCacheDir, но первый подход намного проще.

К сожалению, не существует более элегантного решенияна данный момент.

3 голосов
/ 24 января 2015

Ниже приведена процедура GetMethodID / CallObjectMethod, на которую ссылается Эртеболле.Это необходимо, если вы работаете с чистым собственным приложением (например, созданным Visual Studio 2015) и не можете использовать код Java.

std::string android_temp_folder( struct android_app *app ) {
    JNIEnv* env;
    app->activity->vm->AttachCurrentThread( &env, NULL );

    jclass activityClass = env->FindClass( "android/app/NativeActivity" );
    jmethodID getCacheDir = env->GetMethodID( activityClass, "getCacheDir", "()Ljava/io/File;" );
    jobject cache_dir = env->CallObjectMethod( app->activity->clazz, getCacheDir );

    jclass fileClass = env->FindClass( "java/io/File" );
    jmethodID getPath = env->GetMethodID( fileClass, "getPath", "()Ljava/lang/String;" );
    jstring path_string = (jstring)env->CallObjectMethod( cache_dir, getPath );

    const char *path_chars = env->GetStringUTFChars( path_string, NULL );
    std::string temp_folder( path_chars );

    env->ReleaseStringUTFChars( path_string, path_chars );
    app->activity->vm->DetachCurrentThread();
    return temp_folder;
}
0 голосов
/ 31 марта 2014

mkstemp доступен в NDK по адресу stdlib.h

0 голосов
/ 26 апреля 2012

Насколько я знаю, в android нет глобальных / tmp, вы должны использовать кеш dir.Используйте getCacheDir () для получения директории "tmp".

http://developer.android.com/guide/topics/data/data-storage.html#filesInternal и http://developer.android.com/reference/android/content/Context.html#getCacheDir%28%29

...