在android中使用JNI检索持久数据

时间:2013-05-31 12:27:50

标签: android android-ndk java-native-interface

我正在编写一个Android应用程序,我需要有两个必须由应用程序读取的持久值。应用程序需要维护一个计数器,该计数器必须存储在“somehwhere”并在每次启动Activity时检索。然后更新计数器,然后在关闭活动之前存储。

重要的是,我希望计数器的存储和检索由我的代码的JNI部分完成。它应该对Java代码几乎不可见。可以使用JNI访问此计数器(内存)吗?如果是这样,你能指出我必须看哪个API吗? 我知道可以在Java端使用SQLiteDatabase。请指教!

2 个答案:

答案 0 :(得分:3)

这是完全可能的,但不是没有一些Java代码。

编辑:提供以下内容作为数据库的替代方案。能够从本机代码读取和写入文件中的持久性数据将比数据库灵活得多......

假设您要存储和检索驻留在文件系统上的文件(二进制或纯文本)中的某些数据,这些步骤将采取以下步骤:

  1. JAVA:获取应用的存储位置,并检查它是否可供阅读和写作

  2. JAVA:如果以上是肯定的,请通过JNI将其传递给原生图层

  3. NATIVE:使用存储参数读取/写入文件

  4. 好的,到目前为止摘要;让我们来看看代码:

    1A)检索并检查存储空间:

    private boolean checkExternalStorageState(){
            String state = Environment.getExternalStorageState();
    
            if (Environment.MEDIA_MOUNTED.equals(state)) {
                // We can read and write the media
                android.util.Log.i("YourActivity", "External storage is available for read/write...", null);
                return true;
            } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
                // We can only read the media : NOT ok
                android.util.Log.e("YourActivity", "External storage is read only...", null);
                return false;
            } else {
                // Something else is wrong. It may be one of many other states, but all we need
                //  to know is we can neither read nor write
                android.util.Log.e("YourActivity", "External storage is not mounted or read only...", null);
                return false;
            }
        }
    

    获取存储位置:

    private get storageLocation(){
        File externalAppDir = getExternalFilesDir(null);
        String storagePath = externalAppDir.getAbsolutePath()
    }
    

    1B)您也可能想检查文件是否存在(您也可以在本机部分执行此操作)

    private boolean fileExists(String file) {
    
            String filePath = storagePath + "/" + file;
    
            // see if our file exists
            File dataFile = new File(filePath);
            if(dataFile.exists() && dataFile.isFile())
            {
                // file exists
                return true;
            }
            else
            {
                // file does not exist
                return false;
            }
        }
    

    2)将其传递给原生图层:

    JAVA部分:

    // Wrapper for native library
    public class YourNativeLib {
    
    
         static {
             // load required libs here
             System.loadLibrary("yournativelib");
         }
    
         public static native long initGlobalStorage(String storagePath);
         ...enter more functions here
    
    }
    

    NATIVE部分:

    JNIEXPORT jlong JNICALL Java_com_whatever_YourNativeLib_initGlobalStorage(JNIEnv *env, jobject obj, jstring storagePath)
    {
        jlong data = 0;
    
        // convert strings
        const char *myStoragePath = env->GetStringUTFChars(storagepath, 0);
        // and now you can use "myStoragePath" to read/write files in c/c++
    
        //release strings
        env->ReleaseStringUTFChars(storagePath, myStoragePath);
    
        return data;
    }
    

    如何在c / c ++中读取/写入二进制文件或文本文件已有详细记录,我将把它留给您。

答案 1 :(得分:1)

您可以通过在项目中包含SQLite合并(http://www.sqlite.org/download.html)来使用NDK端的SQLite。

请参阅SQLite with Android NDK