I am trying to implement a way to check device native resolution, and as it seems, at least with Android one would need to use JNI for that.
Been goggling and following some guides online, but still no luck. I guess my understanding of JNI logic is broken
For example, a simple dummy method returning a string …
Java part:
public class Common {
public static String getResolution()
{
// Dummy method for now...
return "320x240";
}
}
C+ part:* JNI
Where do add this?
I see some people modify the framework bindings “cocos2dx\platform\android\jni”.
But I would like to leave the framework intact, so I’m adding it to project folder “proj.android\jni\myapp\main.cpp”
<pre>
// Get device resolution
JNIEXPORT jstring JNICALL Java_com_myapp_Common_getResolution
{
// Dummy for now…
jstring jstr = env->NewStringUTF;
return jstr;
} </pre>
This compiles fine, but now how to access this method from C+ project classes ?
**from project Classes*
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include // is this needed ?
char* value = Java_com_myapp_Common_getResolution();
#endif
This won’t compile successfully, method not declared.
Can someone help me understand the logic of JNI ?
error: 'Java_com_myapp_Common_getResolution' was not declared in this scope
Ok, managed to achieve my goal.
I think the approach in first comment is meant to be used in invoking C*+ method from Java.
So my goal was to invoke a Java method from C**, more precisely to get android device native resolution.
Let’s start with Java part:
We need to define the method we want to invoke from C*+.
I’ll create a static method and since I’ll need to get the class instance in order to system services, I’ll add a static private member to hold it’s value.
public class MyGame extends Cocos2dxActivity{
// assign class instance
static private MyGame instance;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// assign self instance
Samecolor.instance = this;
}
(...)
// Get resolution size
static public int[] getResolution()
{
// get application
Context context = Samecolor.instance;
// get window manager and display
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
// create array with size
int size[] = {display.getWidth(), display.getHeight()};
// return size
return size;
}
And now the C++ part:
All JNI core is meant to be used with Android, so we’ll need to wrap some code #if#endif directives.
If not it will fail to compile in any all other platforms.
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// include JniHelper.h
#include "platform\android\jni\JniHelper.h"
#endif
#include "cocos2d.h"
USING_NS_CC;
(...)
static CCSize getDeviceResolutionX()
{
CCSize res = CCSize(0.0f, 0.0f);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo t;
// get method 'getResolution' which returns int array '()[I' from java package 'com.mygame' & 'MyGame' class
if (JniHelper::getStaticMethodInfo(t,
"com/mygame/MyGame",
"getResolution",
"()[I"))
{
// get int array
jintArray ret = (jintArray)t.env->CallObjectMethod(t.classID, t.methodID);
// delete reference
t.env->DeleteLocalRef(t.classID);
if (ret)
{
// get array values
jint *oarr = t.env->GetIntArrayElements(ret, NULL);
// assign array values to CCSize
res.width = (float)oarr[0];
res.height = (float)oarr[1];
// release array values
t.env->ReleaseIntArrayElements(ret, oarr, NULL);
}
}
#endif
// return CCSize
return res;
}
Feel free to point out possible issues/performance, I’m sure there’s room to improvement