您的位置:首页 > 移动开发 > Cocos引擎

native app 集成 cocos-2dx-js 3.11 (Android篇)

2016-07-19 14:45 387 查看
接上篇,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 comment
a3cc
ed 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切换时内存释放有小量泄露还需要进一步处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息