接上篇,android的集成相对麻烦一些,其中涉及到修改引擎底层功能,以下只记录一些其过程中关键步骤,有时间在写ndkgdb debug问题定位处理等等填坑过程。
1、添加引擎java部分
2、添加编译native库
3、增加 CocosJSActivity
/****************************************************************************
CocosJSActivity
****************************************************************************/
package org.cocos2dx.javascript;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class CocosJSActivity extends Cocos2dxActivity {
public static Context preContext = null;
private static native void nativeSetContext(final Context pContext);
public static CocosJSActivity appCocosActivity = null;
static public void setClassLoaderFrom(Context cxt){
preContext = cxt;
nativeSetContext(cxt);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appCocosActivity = this;
}
@Override
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
return glSurfaceView;
}
public static void backToNativeAppView(final String title,final String message) {
appCocosActivity.getGLSurfaceView().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(appCocosActivity.getContext(), MainActivity.class);
appCocosActivity.getContext().startActivity(intent);
}
},80);
}
public static void loadNativeLibraries() {
try {
String libName = "cocos2djs";
System.loadLibrary(libName);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void EnterGameLobby(){
nativeEnterGameLobby();
}
public static void nativeActionCallBack(){
android.util.Log.d("CocosJSActivity", "nativeActionCallBack");
Intent intent = new Intent(preContext, CocosJSActivity.class);
preContext.startActivity(intent);
}
private static native void nativeEnterGameLobby();
private static native void nativeEnd();
private static native void nativeBackGame();
private static native void cleanupJSvm();
}
4、MainActivity中的调用
/****************************************************************************
****************************************************************************/
package org.cocos2dx.javascript;
import org.cocos2dx.WebGame.R;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button button = null;
public static MainActivity instance = null;
private static native void nativeSetContext(final Context pContext);
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
button = (Button)findViewById(R.id.button_second);
button.setOnClickListener(new MyButtonListener());
instance = this;
loadNativeLibraries();
CocosJSActivity.setClassLoaderFrom(this);
}
public static void loadNativeLibraries() {
try {
String libName = "cocos2djs";
System.loadLibrary(libName);
} catch (Exception e) {
e.printStackTrace();
}
}
class MyButtonListener implements OnClickListener
{
@Override
public void onClick(View v) {
CocosJSActivity.EnterGameLobby();
}
}
}
5、native 需要修改的地方
(1)在合适文件中添加内存释放方法,在切换回 native app 时调用
void cocos_android_app_releseCocosApp() {
delete cocos2d::Application::getInstance();
}
(2)添加入口调用方法
void Java_CocosJSActivity_nativeEnterGameLobby(JNIEnv* env, jobject thiz) {
GameManager::getInstance()->EnterGameLobby(env, "todo");
}
(3)添加初始化JVM环境接口
JNIEXPORT void JNICALL Java_CocosJSActivity_nativeSetContext(JNIEnv* env, jobject thiz, jobject context) {
JniHelper::setClassLoaderFrom(context);
}
(4)修改AppDelegate入口
bool AppDelegate::applicationDidFinishLaunching()
{
return GameManager::getInstance()->EnterCocos();
}
(5)实现gameManager
bool nativeActionCallBack() __attribute__((weak));
GameManager * GameManager::instance = NULL;
GameManager * GameManager::getInstance(){
if (!instance)
{
instance = new GameManager();
}
return instance;
};
GameManager::GameManager(){
}
GameManager::~GameManager(){
}
void GameManager::EnterGameLobby(JNIEnv* env, char * gameId){
LOGD("EnterGameLobby");
//to do
m_argString = "gameId=“+gameId;
cocos2d::JniMethodInfo t;
static const std::string className = "org/cocos2dx/javascript/CocosJSActivity";
if (cocos2d::JniHelper::getStaticMethodInfo(t
, className.c_str()
, "nativeActionCallBack"
, "()V"))
{
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
};
bool GameManager::EnterCocos(){
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
glview = cocos2d::GLViewImpl::create("WebGame");
#else
glview = cocos2d::GLViewImpl::createWithRect("WebGame", Rect(0,0,960,640));
#endif
director->setOpenGLView(glview);
}
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
director->startAnimation();
ScriptingCore* sc = ScriptingCore::getInstance();
sc->addRegisterCallback(register_all_cocos2dx);
sc->addRegisterCallback(register_cocos2dx_js_core);
sc->addRegisterCallback(jsb_register_system);
// extension can be commented out to reduce the package
sc->addRegisterCallback(register_all_cocos2dx_extension);
sc->addRegisterCallback(register_all_cocos2dx_extension_manual);
// chipmunk can be commented out to reduce the package
sc->addRegisterCallback(jsb_register_chipmunk);
// opengl can be commented out to reduce the package
sc->addRegisterCallback(JSB_register_opengl);
// builder can be commented out to reduce the package
sc->addRegisterCallback(register_all_cocos2dx_builder);
sc->addRegisterCallback(register_CCBuilderReader);
// ui can be commented out to reduce the package, attension studio need ui module
sc->addRegisterCallback(register_all_cocos2dx_ui);
sc->addRegisterCallback(register_all_cocos2dx_ui_manual);
// studio can be commented out to reduce the package,
sc->addRegisterCallback(register_all_cocos2dx_studio);
sc->addRegisterCallback(register_all_cocos2dx_studio_manual);
// spine can be commented out to reduce the package
sc->addRegisterCallback(register_all_cocos2dx_spine);
sc->addRegisterCallback(register_all_cocos2dx_spine_manual);
// XmlHttpRequest can be commented out to reduce the package
sc->addRegisterCallback(MinXmlHttpRequest::_js_register);
// websocket can be commented out to reduce the package
sc->addRegisterCallback(register_jsb_websocket);
// sokcet io can be commented out to reduce the package
sc->addRegisterCallback(register_jsb_socketio);
// 3d can be commented out to reduce the package
sc->addRegisterCallback(register_all_cocos2dx_3d);
sc->addRegisterCallback(register_all_cocos2dx_3d_manual);
// 3d extension can be commented out to reduce the package
sc->addRegisterCallback(register_all_cocos2dx_3d_extension);
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
// Physics 3d can be commented out to reduce the package
sc->addRegisterCallback(register_all_cocos2dx_physics3d);
sc->addRegisterCallback(register_all_cocos2dx_physics3d_manual);
#endif
#if CC_USE_NAVMESH
sc->addRegisterCallback(register_all_cocos2dx_navmesh);
sc->addRegisterCallback(register_all_cocos2dx_navmesh_manual);
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
sc->addRegisterCallback(register_all_cocos2dx_experimental_video);
sc->addRegisterCallback(register_all_cocos2dx_experimental_video_manual);
sc->addRegisterCallback(register_all_cocos2dx_experimental_webView);
sc->addRegisterCallback(register_all_cocos2dx_experimental_webView_manual);
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
sc->addRegisterCallback(register_all_cocos2dx_audioengine);
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
sc->addRegisterCallback(JavascriptJavaBridge::_js_register);
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
sc->addRegisterCallback(JavaScriptObjCBridge::_js_register);
#endif
sc->start();
sc->runScript("script/jsb_boot.js");
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
sc->enableDebugger();
#endif
ScriptEngineProtocol *engine = ScriptingCore::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(engine);
ScriptingCore::getInstance()->runScript("main.js");
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
jsval args[1];
args[0] = std_string_to_jsval(cx, m_argString);
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(sc->getGlobalObject()), "EnterCocos", 1, args);
return true;
};
(6)修改 ScriptingCore,以达到切换native时能释放jsvm内存,重新初始化的目的
ScriptingCore *ScriptingCore::instance = nullptr;
ScriptingCore* ScriptingCore::getInstance()
{
if (instance == nullptr)
instance = new (std::nothrow) ScriptingCore();
return instance;
}
void ScriptingCore::restartVM()
{
cleanup();
initRegister();
// Application::getInstance()->applicationDidFinishLaunching();
}
ScriptingCore::~ScriptingCore()
{
cleanup();
JS_ShutDown();
instance = nullptr;
}
总结:
比ios版本的集成要复杂得多很多, 效果达到预期,native与cocos切换时内存释放有小量泄露还需要进一步处理。