2011-09-29 33 views
18

Tôi hiện đang làm việc trên một ứng dụng Android dựa trên C dựa trên NDK. Ứng dụng này cần tạo tệp tạm thời. Trên một hệ thống Linux thông thường, tôi sẽ sử dụng tmpfile để đảm bảo rằng các tệp này được tạo đúng cách trong một thư mục tạm thời và được dọn sạch ở cuối quá trình.Tạo các tệp tạm thời trong Android với NDK

Tuy nhiên, cuộc điều tra của tôi trên các thiết bị Android khác nhau dường như chỉ ra rằng

  • tmpfile luôn thất bại;
  • không có thư mục /tmp;
  • thư mục /data/local/tmp không có trên tất cả các biến thể của Android;
  • không có TEMP bộ biến môi trường;
  • mkstemp không hoạt động tốt hơn tmpfile.

Bây giờ, tôi chắc chắn rằng tôi có thể hack thứ gì đó lại với nhau, nhưng thấy rằng SDK cung cấp context.getCacheDirFile.createTempFile cho các ứng dụng Java, tôi hy vọng rằng có tương đương ở cấp C.

Có ai biết phương pháp đáng tin cậy và đa phương tiện tốt để tạo tệp tạm thời không?

Trả lời

9

Cách tốt nhất mà chúng tôi tìm thấy là gọi Context.getCacheDir khi khởi động, nhận đường dẫn với getAbsolutePath, sau đó gọi hàm JNI để lưu trữ đường dẫn đó trong toàn cầu. Bất kỳ chức năng nào muốn tạo tệp tạm thời chỉ cần gắn thêm tên tệp tạm thời phù hợp vào đường dẫn đó.

Nếu bạn thực sự muốn lấy nó từ JNI thay thế khác sẽ được vượt qua trong một Context để một hàm JNI và sử dụng một loạt các GetMethodID/CallObjectMethod công cụ để gọi lại vào Java để getCacheDir, nhưng cách tiếp cận cũ là rất nhiều đơn giản hơn.

Thật không may, hiện tại dường như không phải là giải pháp thanh lịch hơn.

+2

Có thể sử dụng 'libcore' để gọi' setenv() ', xem http://stackoverflow.com/a/22315463/192373. Đây có thể là một cách thanh lịch hơn để hiển thị tên của bộ đệm ẩn cho người bản xứ. –

0

mkstemp có sẵn trong NDK dưới stdlib.h

+0

Điều này có hữu ích không? Tôi nghĩ rằng mkstemp tiêu thụ một 'template' chứa đường dẫn đầy đủ đến một thư mục tạm thời. –

2

Dưới đây là thủ tục GetMethodID/CallObjectMethod rằng Ertebolle đề cập đến. Nó là cần thiết nếu bạn đang làm việc với một ứng dụng thuần túy nguyên bản (chẳng hạn như được xây dựng bởi Visual Studio 2015) và không thể sử dụng mã 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; 
} 
Các vấn đề liên quan