StoreType.java
, add the newly managed integer type to the enumeration:public enum StoreType { Integer, String }
Store.java
and define the new integer functionalities our native store provides:public class Store { ... public native int getCount(); public native int getInteger(String pKey); public native void setInteger(String pKey, int pInt); public native String getString(String pKey); public native void setString(String pKey, String pString); }
StoreActivity
class, update the onGetValue()
method to retrieve integer entries from the store when they are selected in the GUI:public class StoreActivity extends Activity { ... public static class PlaceholderFragment extends Fragment { ... private void onGetValue() { ... switch (type) { case Integer: mUIValueEdit.setText(Integer.toString(mStore .getInteger(key))); break; case String: mUIValueEdit.setText(mStore.getString(key)); break; } } ...
onSetValue()
method. The entry data needs to be parsed before being passed to the native side:... private void onSetValue() { ... try { switch (type) { case Integer: mStore.setInteger(key, Integer.parseInt(value)); break; case String: mStore.setString(key, value); break; } } catch (Exception eException) { displayMessage("Incorrect value."); } updateTitle(); } ... } }
jni/Store.h
, append the integer type in the native StoreType
enumeration and the StoreValue
union:... typedef enum { StoreType_Integer, StoreType_String } StoreType; typedef union { int32_t mInteger; char* mString; } StoreValue; ...
jni/com_packtpub_Store.h
with javah
. Two new methods Java_com_packtpub_store_Store_getInteger()
and Java_com_packtpub_store_Store_getInteger()
should appear.jni/com_packtpub_Store.cpp
, implement getInteger()
with the help of the generated JNI header. This method simply returns the integer value of an entry without doing any specific conversion other than an implicit cast from int32_t
to jint
. If any problem occurs, during retrieval, a default value is returned:... JNIEXPORT jint JNICALL Java_com_packtpub_store_Store_getInteger (JNIEnv* pEnv, jobject pThis, jstring pKey) { StoreEntry* entry = findEntry(pEnv, &gStore, pKey); if (isEntryValid(pEnv, entry, StoreType_Integer)) { return entry->mValue.mInteger; } else { return 0; } } ...
setInteger()
stores the given integer value in the allocated entry. Note how here too that the passed JNI integer can be reversely cast to a C/C++ integer:... JNIEXPORT void JNICALL Java_com_packtpub_store_Store_setInteger (JNIEnv* pEnv, jobject pThis, jstring pKey, jint pInteger) { StoreEntry* entry = allocateEntry(pEnv, &gStore, pKey); if (entry != NULL) { entry->mType = StoreType_Integer; entry->mValue.mInteger = pInteger; } }
Run the application. Try to save a few entries with different keys, types, and values. Then try to get them back from the native store. We have this time managed to pass and retrieve integer primitives from Java to C/C++.
Integer primitives wear several dresses during native calls; first, int
in Java code, then jint
during transfer from/to Java code, and finally, int
or int32_t
in native code. Obviously, we could have kept the JNI representation
jint
in native code if we wanted to, since all of these types are simply equivalent. In other words, jint
is simply an alias.
All primitive types have their proper alias in JNI:
Java type |
JNI type |
C type |
Stdint C type |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You can use them exactly the same way we used integers in this part. More information about primitive types in JNI can be found at http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html
18.191.5.239