使用NDK在Android中创建临时文件

问题描述 投票:18回答:5

我目前正在研究基于C,基于NDK的Android应用程序。该应用程序需要创建临时文件。在常规Linux系统上,我将使用tmpfile确保在临时目录中正确创建这些文件并在进程结束时进行清理。

但是,我对各种Android设备的调查似乎表明这一点

  • tmpfile总是失败;
  • 没有/tmp目录;
  • 目录/data/local/tmp并非在所有Android版本中都存在;
  • 没有设置TEMP环境变量;
  • [mkstemp没有比tmpfile更好的工作。

[现在,我确定可以一起破解某些东西,但是看到SDK为Java应用程序提供了context.getCacheDirFile.createTempFile,我希望在C级别上有同等的东西。

有人知道用于创建临时文件的可靠且跨Android的良好方法吗?

android-ndk temporary-files
5个回答
9
投票

[我们发现的最佳方法是在启动时调用Context.getCacheDir,使用getAbsolutePath获取其路径,然后调用JNI函数将该路径存储在全局路径中。任何想要创建临时文件的功能都只是将适当的临时文件名附加到该路径。

[如果您真的想从JNI中获取它,另一种选择是将Context传递给JNI函数,并使用一堆GetMethodID / CallObjectMethod东西将Java回调到getCacheDir,但是前一种方法要简单得多。

不幸的是,目前似乎没有一个更优雅的解决方案。


3
投票

下面是Ertebolle引用的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
投票

据我所知,在android中没有全局/ tmp,您应该使用cache dir。使用getCacheDir()获取“ tmp”目录。

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


0
投票

mkstemp在NDK的stdlib.h下可用


0
投票
  1. 使用ContentProvider获取在应用程序启动时缓存目录的路径。
  2. 使用与POSIX的tmpfile相同的签名实现tmpfile函数。
  3. 使用先前获得的缓存目录从tmpfile函数调用mkstemp

打包为.aar,因此可以通过gradle使用。

https://github.com/ViliusSutkus/tmpfile

© www.soinside.com 2019 - 2024. All rights reserved.