.examples Fix AndroidMath MemoryManger class

git-svn-id: svn://ultimatepp.org/upp/trunk@9573 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
klugier 2016-03-06 12:42:09 +00:00
parent 9bfb121075
commit f5c559e7b8
7 changed files with 94 additions and 51 deletions

View file

@ -7,9 +7,4 @@ public class AndroidMath
// Native stuff - C/C++
public static native int power(int number, int n);
static {
// In this place we are loading native libraries.
// Native library always has upp package name!
System.loadLibrary("AndroidMath");
}
}

View file

@ -3,6 +3,9 @@ description "Android builder juicy example\377";
uses
AndroidMathUtility;
library
log;
file
MemoryManager readonly separator,
MemoryManager.h,

View file

@ -59,4 +59,15 @@ public class AndroidMathActivity extends Activity
tv.append(text);
}
static {
// For Android version less than 5.0 we need to specific standard library
// System.loadLibrary("gnustl_shared");
System.loadLibrary("c++_shared");
// In this place we are loading native libraries (In revers dependency order).
// IMPORTANT: Native library always has upp package name!!!
System.loadLibrary("AndroidMathUtility");
System.loadLibrary("AndroidMath");
}
}

View file

@ -1,8 +1,16 @@
#ifndef _JniMath_MemoryManager_h_
#define _JniMath_MemoryManager_h_
#include <android/log.h>
#include <jni.h>
#include <vector>
#include <string>
#include <sstream>
#define FIELD_NATIVE_ADRESS "nativeAdress"
#define LONG_SIG "J"
/**
* Java simple memory manager.
@ -10,36 +18,41 @@
template <class T>
class MemoryManager {
public:
void Insert(JNIEnv *env, jobject jobj, const T& obj)
~MemoryManager()
{
jobject weakGlobalRef = env->NewWeakGlobalRef(jobj);
if(!env->IsSameObject(weakGlobalRef, NULL)) {
objs.push_back(env->NewWeakGlobalRef(weakGlobalRef));
values.push_back(obj);
for(int i = 0; i < values.size(); i++) {
delete values[i];
}
}
void Insert(JNIEnv *env, jobject jobj, T* value)
{
if(jobj != NULL) {
values.push_back(value);
SetNativeAdress(env, jobj, values[values.size() - 1]);
}
}
void MakeCopy(JNIEnv *env, jobject jobjSrc, jobject jobjDst)
void MakeCopy(JNIEnv *env, jobject jobjThis, jobject jobjThat)
{
if(!env->IsSameObject(jobjSrc, jobjDst)) {
T t(*Get(env, jobjSrc));
Insert(env, jobjSrc, t);
if(!env->IsSameObject(jobjThis, jobjThat)) {
T* t = Get(env, jobjThat);
Insert(env, jobjThis, t);
}
}
void Erase(JNIEnv *env, jobject jobj)
{
int idx = FindIdx(env, jobj);
if(idx >= 0) {
objs.erase(objs.begin() + idx);
if(idx >= 0)
values.erase(values.begin() + idx);
}
}
T* Get(JNIEnv *env, jobject jobj)
{
int idx = FindIdx(env, jobj);
return idx >= 0 ? &values[idx] : NULL;
return idx >= 0 ? values[idx] : NULL;
}
int GetCount()
@ -50,17 +63,38 @@ public:
private:
int FindIdx(JNIEnv *env, jobject jobj)
{
for(int i = 0; i < objs.size(); i++) {
if(env->IsSameObject(objs[i], jobj)) {
for(int i = 0; i < values.size(); i++) {
if(GetNativeAdress(env, jobj) == values[i]) {
return i;
}
}
return 0;
return -1;
}
private:
std::vector<jobject> objs;
std::vector<T> values;
T* GetNativeAdress(JNIEnv* env, jobject jobj)
{
jclass objectClass = env->GetObjectClass(jobj);
jfieldID adressField = GetNativeAdressField(env, objectClass);
return (T*)env->GetLongField(jobj, adressField);
}
void SetNativeAdress(JNIEnv* env, jobject jobj, T* obj)
{
jclass objectClass = env->GetObjectClass(jobj);
jfieldID adressField = GetNativeAdressField(env, objectClass);
env->SetLongField(jobj, adressField, (jlong)obj);
}
jfieldID GetNativeAdressField(JNIEnv* env, jclass clazz)
{
return env->GetFieldID(clazz, FIELD_NATIVE_ADRESS, LONG_SIG);
}
private:
std::vector<T*> values;
};
#endif

View file

@ -17,7 +17,7 @@ extern "C" {
using AndroidMathUtility::Vector;
MemoryManager<Vector> mm;
static MemoryManager<Vector> mm;
/*
* Class: org_upp_AndroidMath_Vector
@ -27,7 +27,7 @@ MemoryManager<Vector> mm;
JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_construct
(JNIEnv *env, jobject obj, jint size)
{
mm.Insert(env, obj, Vector(size));
mm.Insert(env, obj, new Vector(size));
}
/*
@ -36,9 +36,9 @@ JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_construct
* Signature: (Lorg/upp/AndroidMath/Vector;)V
*/
JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_copyConstruct
(JNIEnv *env, jobject objSrc, jobject objDst)
(JNIEnv *env, jobject jobjThis, jobject jobjThat)
{
mm.MakeCopy(env, objSrc, objDst);
mm.MakeCopy(env, jobjThis, jobjThat);
}
/*
@ -46,7 +46,7 @@ JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_copyConstruct
* Method: destruct
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_destroy
JNIEXPORT void JNICALL Java_org_upp_AndroidMath_Vector_nativeFinalize
(JNIEnv *env, jobject obj)
{
mm.Erase(env, obj);

View file

@ -5,6 +5,23 @@ package org.upp.AndroidMath;
*/
public class Vector
{
/**
* Field use by MemoryManager to stroe pointer to c++ object.
* If you want to use MemoryManager with your class make usre you have this field
* in your class.
*/
private long nativeAdress = 0;
/**
* We override finalize method, beacuse we need to destroy native c++ object.
*/
@Override
protected void finalize() throws Throwable
{
nativeFinalize();
super.finalize();
}
public Vector(int size)
{
construct(size);
@ -15,16 +32,6 @@ public class Vector
copyConstruct(vec);
}
/**
* We override finalize method due to possibilite of memory leaks.
*/
@Override
protected void finalize() throws Throwable
{
destroy();
super.finalize();
}
// Native stuff - C/C++
public native int getSize();
public native float get(int id);
@ -37,11 +44,5 @@ public class Vector
private native void construct(int size);
private native void copyConstruct(Vector vec);
private native void destroy();
static {
// In this place we are loading native libraries.
// Native library always has upp package name!
System.loadLibrary("AndroidMath");
}
private native void nativeFinalize();
}

View file

@ -22,10 +22,10 @@ Vector::Vector(int size)
Vector::Vector(const Vector& vec)
{
if(vec.GetSize() > 0) {
size = vec.GetSize();
data = new float[size];
this->size = vec.GetSize();
this->data = new float[size];
for(int i = 0; i < size; i++) {
data[i] = vec.data[i];
this->data[i] = vec.data[i];
}
}
else {
@ -36,8 +36,7 @@ Vector::Vector(const Vector& vec)
Vector::~Vector()
{
if(data != NULL)
delete[] data;
//delete[] data;
}
float Vector::Get(int id) const