比较老的Cocos2d游戏在Android5.0的兼容问题

比较老的Cocos2d游戏在Android5.0的兼容问题.

有许多的Cocos2d游戏是在Android5.0之前开发的,把原来的游戏安装到Android5.0或更高版本的安卓机后发现会出现很多问题.

刚遇到时也是一筹莫展.大概只是知道Android5.0对jni要求更加的规范了.

而Cocos2d为我们封装了一个很好用的类JniHelper.所以自然想到问题可能出现在这里.

废话不多说.

直接把原Cocos2d中的 如图:


这三个文件修改下,问题就解决了!

代码如下:


1.JniHlper.h


#ifndef __ANDROID_JNI_HELPER_H__#define __ANDROID_JNI_HELPER_H__#include#include#include "CCPlatformMacros.h"

namespace cocos2d {

typedef struct JniMethodInfo_

{

JNIEnv *    env;

jclass      classID;

jmethodID  methodID;

} JniMethodInfo;

class CC_DLL JniHelper

{

public:

static JavaVM* getJavaVM();

static void setJavaVM(JavaVM *javaVM);

static jclass getClassID(const char *className, JNIEnv *env=0);

static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);

static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);

static std::string jstring2string(jstring str);

private:

static JavaVM *m_psJavaVM;

};

}

#endif // __ANDROID_JNI_HELPER_H__


2.JniHlper.cpp


#include "JniHelper.h"#include#include#if 1

#define  LOG_TAG    "JniHelper"

#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

#else

#define  LOGD(...)

#endif

#define JAVAVM cocos2d::JniHelper::getJavaVM()

using namespace std;

extern "C"

{

//////////////////////////////////////////////////////////////////////////

// java vm helper function

//////////////////////////////////////////////////////////////////////////

static bool getEnv(JNIEnv **env)

{

bool bRet = false;

do

{

if (JAVAVM->GetEnv((void**)env, JNI_VERSION_1_4) != JNI_OK)

{

LOGD("Failed to get the environment using GetEnv()");

break;

}

if (JAVAVM->AttachCurrentThread(env, 0) < 0)

{

LOGD("Failed to get the environment using AttachCurrentThread()");

break;

}

bRet = true;

} while (0);

return bRet;

}

static jclass getClassID_(const char *className, JNIEnv *env)

{

JNIEnv *pEnv = env;

jclass ret = 0;

do

{

if (! pEnv)

{

if (! getEnv(&pEnv))

{

break;

}

}

ret = pEnv->FindClass(className);

if (! ret)

{

LOGD("Failed to find class of %s", className);

break;

}

} while (0);

return ret;

}

static bool getStaticMethodInfo_(cocos2d::JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)

{

jmethodID methodID = 0;

JNIEnv *pEnv = 0;

bool bRet = false;

do

{

if (! getEnv(&pEnv))

{

break;

}

jclass classID = getClassID_(className, pEnv);

methodID = pEnv->GetStaticMethodID(classID, methodName, paramCode);

if (! methodID)

{

LOGD("Failed to find static method id of %s", methodName);

break;

}

methodinfo.classID = classID;

methodinfo.env = pEnv;

methodinfo.methodID = methodID;

bRet = true;

} while (0);

return bRet;

}

static bool getMethodInfo_(cocos2d::JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)

{

jmethodID methodID = 0;

JNIEnv *pEnv = 0;

bool bRet = false;

do

{

if (! getEnv(&pEnv))

{

break;

}

jclass classID = getClassID_(className, pEnv);

methodID = pEnv->GetMethodID(classID, methodName, paramCode);

if (! methodID)

{

LOGD("Failed to find method id of %s", methodName);

break;

}

methodinfo.classID = classID;

methodinfo.env = pEnv;

methodinfo.methodID = methodID;

bRet = true;

} while (0);

return bRet;

}

static string jstring2string_(jstring jstr)

{

JNIEnv *env = 0;

jboolean isCopy;

if (! getEnv(&env))

{

return 0;

}

const char* chars = env->GetStringUTFChars(jstr, &isCopy);

string ret(chars);

if (isCopy)

{

env->ReleaseStringUTFChars(jstr, chars);

}

return ret;

}

}

namespace cocos2d {

JavaVM* JniHelper::m_psJavaVM = NULL;

JavaVM* JniHelper::getJavaVM()

{

return m_psJavaVM;

}

void JniHelper::setJavaVM(JavaVM *javaVM)

{

m_psJavaVM = javaVM;

}

jclass JniHelper::getClassID(const char *className, JNIEnv *env)

{

return getClassID_(className, env);

}

bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)

{

return getStaticMethodInfo_(methodinfo, className, methodName, paramCode);

}

bool JniHelper::getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)

{

return getMethodInfo_(methodinfo, className, methodName, paramCode);

}

string JniHelper::jstring2string(jstring str)

{

return jstring2string_(str);

}

}


3.Java_org_cocos2dx_lib_Cocos2dxHelper.cpp


#include#include#include#include#include "JniHelper.h"

#include "CCFileUtilsAndroid.h"

#include "android/asset_manager_jni.h"

#include "CCString.h"

#include "Java_org_cocos2dx_lib_Cocos2dxHelper.h"

#define  LOG_TAG    "Java_org_cocos2dx_lib_Cocos2dxHelper.cpp"

#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

#define  CLASS_NAME "org/cocos2dx/lib/Cocos2dxHelper"

EditTextCallback s_pfEditTextCallback = NULL;

void* s_ctx = NULL;

using namespace cocos2d;

using namespace std;

string g_apkPath;

extern "C" {

JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetApkPath(JNIEnv*  env, jobject thiz, jstring apkPath) {

g_apkPath = JniHelper::jstring2string(apkPath);

}

JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetContext(JNIEnv*  env, jobject thiz, jobject context, jobject assetManager) {

//JniHelper::setClassLoaderFrom(context);

FileUtilsAndroid::setassetmanager(AAssetManager_fromJava(env, assetManager));

}

JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetEditTextDialogResult(JNIEnv * env, jobject obj, jbyteArray text) {

jsize  size = env->GetArrayLength(text);

if (size > 0) {

jbyte * data = (jbyte*)env->GetByteArrayElements(text, 0);

char* pBuf = (char*)malloc(size+1);

if (pBuf != NULL) {

memcpy(pBuf, data, size);

pBuf[size] = '\0';

// pass data to edittext's delegate

if (s_pfEditTextCallback) s_pfEditTextCallback(pBuf, s_ctx);

free(pBuf);

}

env->ReleaseByteArrayElements(text, data, 0);

} else {

if (s_pfEditTextCallback) s_pfEditTextCallback("", s_ctx);

}

}

}

const char * getApkPath() {

return g_apkPath.c_str();

}

void showDialogJNI(const char * pszMsg, const char * pszTitle) {

if (!pszMsg) {

return;

}

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "showDialog", "(Ljava/lang/String;Ljava/lang/String;)V")) {

jstring stringArg1;

if (!pszTitle) {

stringArg1 = t.env->NewStringUTF("");

} else {

stringArg1 = t.env->NewStringUTF(pszTitle);

}

jstring stringArg2 = t.env->NewStringUTF(pszMsg);

t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1, stringArg2);

t.env->DeleteLocalRef(stringArg1);

t.env->DeleteLocalRef(stringArg2);

t.env->DeleteLocalRef(t.classID);

}

}

void showEditTextDialogJNI(const char* pszTitle, const char* pszMessage, int nInputMode, int nInputFlag, int nReturnType, int nMaxLength, EditTextCallback pfEditTextCallback, void* ctx) {

if (pszMessage == NULL) {

return;

}

s_pfEditTextCallback = pfEditTextCallback;

s_ctx = ctx;

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "showEditTextDialog", "(Ljava/lang/String;Ljava/lang/String;IIII)V")) {

jstring stringArg1;

if (!pszTitle) {

stringArg1 = t.env->NewStringUTF("");

} else {

stringArg1 = t.env->NewStringUTF(pszTitle);

}

jstring stringArg2 = t.env->NewStringUTF(pszMessage);

t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1, stringArg2, nInputMode, nInputFlag, nReturnType, nMaxLength);

t.env->DeleteLocalRef(stringArg1);

t.env->DeleteLocalRef(stringArg2);

t.env->DeleteLocalRef(t.classID);

}

}

void terminateProcessJNI() {

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "terminateProcess", "()V")) {

t.env->CallStaticVoidMethod(t.classID, t.methodID);

t.env->DeleteLocalRef(t.classID);

}

}

std::string getPackageNameJNI() {

JniMethodInfo t;

std::string ret("");

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getCocos2dxPackageName", "()Ljava/lang/String;")) {

jstring str = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);

t.env->DeleteLocalRef(t.classID);

ret = JniHelper::jstring2string(str);

t.env->DeleteLocalRef(str);

}

return ret;

}

std::string getFileDirectoryJNI() {

JniMethodInfo t;

std::string ret("");

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getCocos2dxWritablePath", "()Ljava/lang/String;")) {

jstring str = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);

t.env->DeleteLocalRef(t.classID);

ret = JniHelper::jstring2string(str);

t.env->DeleteLocalRef(str);

}

return ret;

}

std::string getCurrentLanguageJNI() {

JniMethodInfo t;

std::string ret("");

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getCurrentLanguage", "()Ljava/lang/String;")) {

jstring str = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);

t.env->DeleteLocalRef(t.classID);

ret = JniHelper::jstring2string(str);

t.env->DeleteLocalRef(str);

}

return ret;

}

void enableAccelerometerJni() {

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "enableAccelerometer", "()V")) {

t.env->CallStaticVoidMethod(t.classID, t.methodID);

t.env->DeleteLocalRef(t.classID);

}

}

void setAccelerometerIntervalJni(float interval) {

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setAccelerometerInterval", "(F)V")) {

t.env->CallStaticVoidMethod(t.classID, t.methodID, interval);

t.env->DeleteLocalRef(t.classID);

}

}

void disableAccelerometerJni() {

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "disableAccelerometer", "()V")) {

t.env->CallStaticVoidMethod(t.classID, t.methodID);

t.env->DeleteLocalRef(t.classID);

}

}

// functions for UserDefault

bool getBoolForKeyJNI(const char* pKey, bool defaultValue)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getBoolForKey", "(Ljava/lang/String;Z)Z")) {

jstring stringArg = t.env->NewStringUTF(pKey);

jboolean ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg, defaultValue);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

return ret;

}

return defaultValue;

}

int getIntegerForKeyJNI(const char* pKey, int defaultValue)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getIntegerForKey", "(Ljava/lang/String;I)I")) {

jstring stringArg = t.env->NewStringUTF(pKey);

jint ret = t.env->CallStaticIntMethod(t.classID, t.methodID, stringArg, defaultValue);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

return ret;

}

return defaultValue;

}

float getFloatForKeyJNI(const char* pKey, float defaultValue)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getFloatForKey", "(Ljava/lang/String;F)F")) {

jstring stringArg = t.env->NewStringUTF(pKey);

jfloat ret = t.env->CallStaticFloatMethod(t.classID, t.methodID, stringArg, defaultValue);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

return ret;

}

return defaultValue;

}

double getDoubleForKeyJNI(const char* pKey, double defaultValue)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getDoubleForKey", "(Ljava/lang/String;D)D")) {

jstring stringArg = t.env->NewStringUTF(pKey);

jdouble ret = t.env->CallStaticDoubleMethod(t.classID, t.methodID, stringArg, defaultValue);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

return ret;

}

return defaultValue;

}

std::string getStringForKeyJNI(const char* pKey, const char* defaultValue)

{

JniMethodInfo t;

std::string ret("");

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "getStringForKey", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;")) {

jstring stringArg1 = t.env->NewStringUTF(pKey);

jstring stringArg2 = t.env->NewStringUTF(defaultValue);

jstring str = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID, stringArg1, stringArg2);

ret = JniHelper::jstring2string(str);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg1);

t.env->DeleteLocalRef(stringArg2);

t.env->DeleteLocalRef(str);

return ret;

}

return defaultValue;

}

void setBoolForKeyJNI(const char* pKey, bool value)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setBoolForKey", "(Ljava/lang/String;Z)V")) {

jstring stringArg = t.env->NewStringUTF(pKey);

t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg, value);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

}

}

void setIntegerForKeyJNI(const char* pKey, int value)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setIntegerForKey", "(Ljava/lang/String;I)V")) {

jstring stringArg = t.env->NewStringUTF(pKey);

t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg, value);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

}

}

void setFloatForKeyJNI(const char* pKey, float value)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setFloatForKey", "(Ljava/lang/String;F)V")) {

jstring stringArg = t.env->NewStringUTF(pKey);

t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg, value);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

}

}

void setDoubleForKeyJNI(const char* pKey, double value)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setDoubleForKey", "(Ljava/lang/String;D)V")) {

jstring stringArg = t.env->NewStringUTF(pKey);

t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg, value);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg);

}

}

void setStringForKeyJNI(const char* pKey, const char* value)

{

JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setStringForKey", "(Ljava/lang/String;Ljava/lang/String;)V")) {

jstring stringArg1 = t.env->NewStringUTF(pKey);

jstring stringArg2 = t.env->NewStringUTF(value);

t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1, stringArg2);

t.env->DeleteLocalRef(t.classID);

t.env->DeleteLocalRef(stringArg1);

t.env->DeleteLocalRef(stringArg2);

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容