比較老的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閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容