3

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

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

4

2 回答 2

4

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

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

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

  1. JAVA:获取应用的存储位置并检查它是否可用于读写

  2. JAVA : 如果上面是肯定的,通过JNI传给native层

  3. NATIVE :使用存储参数来读/写你的文件

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

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

}

原生部分:

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++ 中读取/写入二进制文件或文本文件已有详细记录,我将由您决定。

于 2013-05-31T14:02:35.457 回答
1

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

使用 Android NDK查看SQLite

于 2013-05-31T13:35:36.553 回答