2012年1月11日 星期三

android sdcard 測速程式 (藉由 Jni)

這次是修改上次寫的測速程式,並把之前寫的c語言測速程式藉由ndk產生.so,改用Jni的方式去呼叫執行。
write_and_read.c
JNIEXPORT
jdouble JNICALL Java_com_omd_speedsdcard_SpeedSDcardActivity_getWriteSpeed(JNIEnv *env, jobject obj){
    double writeDuration, readDuration;
    double writeSpeed, readSpeed;

    char *test = malloc (writeblock*sizeof(char));
    long start_time = getCurrentTime();
    writeToFile(TESTFILEPATH, test, writeblock,testsize);
    long end_time = getCurrentTime();
    free(test);

    writeDuration = (double) (end_time - start_time) / 1000;
    LOGI("write duration: %f\n", writeDuration);
    writeSpeed = testsize / 1024 / 1024 / writeDuration;
    LOGI("write speed: %f MB/s\n", writeSpeed);
    return writeSpeed;
}
JNIEXPORT
jdouble JNICALL Java_com_omd_speedsdcard_SpeedSDcardActivity_getReadSpeed(JNIEnv *env, jobject obj){
    long start_time = getCurrentTime();
    readFromFile(TESTFILEPATH,readblock,testsize);
    long end_time = getCurrentTime();
    double writeDuration, readDuration;
    double writeSpeed, readSpeed;
    readDuration = (double) (end_time - start_time) / 1000;
    LOGI("read duration: %f\n", readDuration);
    readSpeed = testsize / 1024 / 1024 / readDuration;
    LOGI("read speed: %f MB/s\n", readSpeed);

    remove(TESTFILEPATH);
    return readSpeed;
}
要注意的是紅色的兩個字,可加可不加,但加了比較保險,有時沒加可能會莫名其妙造成unsatisfiedlinkerror。之後把function名稱就使用Java+packagename+function名稱就可以了。而另外要注意的一點是,原本的printf要改成LOGX,如以下的define即可,使用起來也跟printf差不多。最後在.c裏面還要修改O_SYNC,雖然加了此參數後能確保寫入後才回傳,但會使速度下降太多,比直接用電腦測還要慢,所以還是用讀寫大檔的方式來降低快取所影響的速度。
 #include <android/log.h>
#define LOG_TAG "infomation"
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG  , LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO   , LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN   , LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , LOG_TAG,__VA_ARGS__)
以上完成.c後,編寫Android.mk,其中紅字是為了上述的LOGX而加。
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := write_and_read
LOCAL_SRC_FILES := write_and_read.c
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
再用android ndk的ndk-build即可產生.so
Compile thumb  : write_and_read <= write_and_read.c
SharedLibrary  : libwrite_and_read.so
Install        : libwrite_and_read.so => libs/armeabi/libwrite_and_read.so
之後在Java中加入以下程式碼,即可呼叫上面所寫的函式。
    public native double getWriteSpeed();
    public native double getReadSpeed();
    public native void setBlockAndSize(long readBlock,long writeBlock,long testSize);
    static {
            System.loadLibrary("write_and_read");
        }
最後是完成圖跟程式apk,還有要注意這種程式不要每天跑,可能會降低SDcard壽命。

http://www.box.com/s/vfmyl0tayqkzexa5qm2b

沒有留言:

張貼留言