Skip to content

Instantly share code, notes, and snippets.

@kakajika
Last active August 29, 2015 14:27
Show Gist options
  • Save kakajika/16b808895dc07c4bf49e to your computer and use it in GitHub Desktop.
Save kakajika/16b808895dc07c4bf49e to your computer and use it in GitHub Desktop.
//
// Created by kaji on 15/08/17.
//
#ifndef JNIUTIL_JNIPARCEL_H
#define JNIUTIL_JNIPARCEL_H
#include <string>
#include <vector>
#include <memory>
#include <jni.h>
using namespace std;
class IParcelable {
public:
IParcelable(JNIEnv *env, jobject jParcelable) {}
virtual ~IParcelable() {}
virtual jobject toJParcelable(JNIEnv *env) = 0;
// static virtual string getClassName() = 0;
};
typedef shared_ptr<vector<bool>> BoolArrayPtr;
typedef shared_ptr<vector<unsigned char>> ByteArrayPtr;
typedef shared_ptr<vector<int>> IntArrayPtr;
typedef shared_ptr<vector<int64_t>> LongArrayPtr;
typedef shared_ptr<vector<float>> FloatArrayPtr;
typedef shared_ptr<vector<double>> DoubleArrayPtr;
typedef shared_ptr<vector<string>> StringArrayPtr;
class JNIParcel {
private:
JNIEnv *mEnv;
jobject obj;
static jclass clazz_Parcel;
static jclass clazz_Parcelable;
static jmethodID Parcel_obtain;
static jmethodID Parcel_recycle;
static jmethodID Parcel_setDataPosition;
static jmethodID Parcelable_writeToParcel;
static jmethodID Parcel_readByte;
static jmethodID Parcel_readInt;
static jmethodID Parcel_readLong;
static jmethodID Parcel_readFloat;
static jmethodID Parcel_readDouble;
static jmethodID Parcel_readString;
static jmethodID Parcel_readParcelable;
static jmethodID Parcel_createBooleanArray;
static jmethodID Parcel_createByteArray;
static jmethodID Parcel_createIntArray;
static jmethodID Parcel_createLongArray;
static jmethodID Parcel_createFloatArray;
static jmethodID Parcel_createDoubleArray;
static jmethodID Parcel_createStringArray;
static jmethodID Parcel_createTypedArray;
static jmethodID Parcel_writeByte;
static jmethodID Parcel_writeInt;
static jmethodID Parcel_writeLong;
static jmethodID Parcel_writeFloat;
static jmethodID Parcel_writeDouble;
static jmethodID Parcel_writeString;
static jmethodID Parcel_writeParcelable;
static jmethodID Parcel_writeBooleanArray;
static jmethodID Parcel_writeByteArray;
static jmethodID Parcel_writeIntArray;
static jmethodID Parcel_writeLongArray;
static jmethodID Parcel_writeFloatArray;
static jmethodID Parcel_writeDoubleArray;
static jmethodID Parcel_writeStringArray;
static jmethodID Parcel_writeTypedArray;
static jobject findClassLoader(JNIEnv *env, string className);
static jobject findParcelableCreator(JNIEnv *env, string className);
public:
JNIParcel(JNIEnv *env, jobject jParcelable);
JNIParcel(JNIEnv *env, jobjectArray jParcelableArray);
JNIParcel(JNIEnv *env);
~JNIParcel();
bool readBool();
jbyte readByte();
jint readInt();
jlong readLong();
jfloat readFloat();
jdouble readDouble();
string readString();
template<class T> shared_ptr<T> readParcelable();
template<class T, class BASE> shared_ptr<BASE> readParcelable();
BoolArrayPtr readBoolArray();
ByteArrayPtr readByteArray();
IntArrayPtr readIntArray();
LongArrayPtr readLongArray();
FloatArrayPtr readFloatArray();
DoubleArrayPtr readDoubleArray();
StringArrayPtr readStringArray();
template<class T> shared_ptr<vector<shared_ptr<T>>> readParcelableArray();
template<class T, class BASE> shared_ptr<vector<shared_ptr<BASE>>> readParcelableArray();
void writeBool(bool val);
void writeByte(jbyte val);
void writeInt(jint val);
void writeLong(jlong val);
void writeFloat(jfloat val);
void writeDouble(jdouble val);
void writeString(string val);
template<class T> void writeParcelable(shared_ptr<T> val);
template<class T, class BASE> void writeParcelable(shared_ptr<BASE> val);
void writeBoolArray(BoolArrayPtr ptr);
void writeByteArray(ByteArrayPtr ptr);
void writeIntArray(IntArrayPtr ptr);
void writeLongArray(LongArrayPtr ptr);
void writeFloatArray(FloatArrayPtr ptr);
void writeDoubleArray(DoubleArrayPtr ptr);
void writeStringArray(StringArrayPtr ptr);
template<class T> void writeParcelableArray(shared_ptr<vector<shared_ptr<T>>> ptr);
template<class T, class BASE> void writeParcelableArray(shared_ptr<vector<shared_ptr<BASE>>> ptr);
jobject toJParcelable(string className);
static void init(JNIEnv *env);
static void deinit(JNIEnv *env);
};
jint JNI_OnLoad(JavaVM * vm, void * reserved );
void JNI_OnUnload(JavaVM * vm, void * reserved );
// Template implementation
template<class T>
shared_ptr<T> JNIParcel::readParcelable() {
return readParcelable<T, T>();
}
template<class T, class BASE>
shared_ptr<BASE> JNIParcel::readParcelable() {
jobject jClassLoader = findClassLoader(mEnv, T::getClassName());
jobject jParcelable = mEnv->CallObjectMethod(obj, Parcel_readParcelable, jClassLoader);
shared_ptr<BASE> ptr = shared_ptr<BASE>(new T(mEnv, jParcelable));
mEnv->DeleteLocalRef(jClassLoader);
mEnv->DeleteLocalRef(jParcelable);
return ptr;
}
template<class T>
shared_ptr<vector<shared_ptr<T>>> JNIParcel::readParcelableArray() {
return readParcelableArray<T, T>();
}
template<class T, class BASE>
shared_ptr<vector<shared_ptr<BASE>>> JNIParcel::readParcelableArray() {
vector<shared_ptr<BASE>> *arrayPtr = new vector<shared_ptr<BASE>>();
jobject jParcelableCreator = findParcelableCreator(mEnv, T::getClassName());
jobjectArray jArray = (jobjectArray) mEnv->CallObjectMethod(obj, Parcel_createTypedArray, jParcelableCreator);
mEnv->DeleteLocalRef(jParcelableCreator);
int length = mEnv->GetArrayLength(jArray);
for (int i=0; i<length; ++i) {
jobject jParcelable = mEnv->GetObjectArrayElement(jArray, i);
arrayPtr->push_back(shared_ptr<BASE>(new T(mEnv, jParcelable)));
mEnv->DeleteLocalRef(jParcelable);
}
mEnv->DeleteLocalRef(jArray);
return shared_ptr<vector<shared_ptr<BASE>>>(arrayPtr);
}
template<class T>
void JNIParcel::writeParcelable(shared_ptr<T> val) {
writeParcelable<T, T>(val);
}
template<class T, class BASE>
void JNIParcel::writeParcelable(shared_ptr<BASE> val) {
T* t = static_cast<T*>(val.get());
jobject jParcelable = t->toJParcelable(mEnv);
mEnv->CallVoidMethod(obj, Parcel_writeParcelable, jParcelable, 0);
mEnv->DeleteLocalRef(jParcelable);
}
template<class T>
void JNIParcel::writeParcelableArray(shared_ptr<vector<shared_ptr<T>>> ptr) {
writeParcelableArray<T, T>(ptr);
}
template<class T, class BASE>
void JNIParcel::writeParcelableArray(shared_ptr<vector<shared_ptr<BASE>>> ptr) {
vector<shared_ptr<BASE>> *array = ptr.get();
int arrSize = array->size();
jobjectArray jArray = mEnv->NewObjectArray(arrSize, clazz_Parcelable, jstring());
typename vector<shared_ptr<BASE>>::iterator it = array->begin();
int i = 0;
while(it != array->end()){
T* t = static_cast<T*>(&*it->get());
mEnv->SetObjectArrayElement(jArray, i, t->toJParcelable(mEnv));
i++;
++it;
}
mEnv->CallVoidMethod(obj, Parcel_writeTypedArray, jArray, 0);
mEnv->DeleteLocalRef(jArray);
}
#endif //JNIUTIL_JNIPARCEL_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment