Creating temporary files in Android with NDK

前端 未结 5 1399
一生所求
一生所求 2020-12-03 07:10

I am currently working on a C-based, NDK-based, Android application. This application needs to create temporary files. On a regular Linux system, I would use tmpfile

相关标签:
5条回答
  • 2020-12-03 07:49

    The best way we've found is to call Context.getCacheDir on startup, get its path with getAbsolutePath, then call a JNI function to store that path in a global. Any function that wants to create a temporary file simply appends a suitable temporary file name to that path.

    If you really want to fetch it from JNI another alternative would be to pass in a Context to a JNI function and use a bunch of GetMethodID / CallObjectMethod stuff to call back into Java to getCacheDir, but the former approach is a lot simpler.

    Unfortunately, there does not appear to be a more elegant solution at the moment.

    0 讨论(0)
  • 2020-12-03 07:53
    1. Obtain path to cache directory on application's startup using a ContentProvider.
    2. Implement tmpfile function with the same signature as POSIX's tmpfile.
    3. Call mkstemp from your tmpfile function using the previously obtained cache directory

    Packaged it as .aar, so it could be consumed through gradle.

    https://github.com/ViliusSutkus89/tmpfile-Android

    0 讨论(0)
  • 2020-12-03 07:54

    Below is the GetMethodID / CallObjectMethod procedure that Ertebolle refers to. It is necessary if you are working with a pure native app (such as built by Visual Studio 2015) and cannot use java code.

    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 讨论(0)
  • 2020-12-03 07:55

    mkstemp is available in the NDK under stdlib.h

    0 讨论(0)
  • 2020-12-03 08:04

    As far as I know there is no global /tmp in android, you should use the cache dir. Use getCacheDir() to get the "tmp" dir.

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

    0 讨论(0)
提交回复
热议问题