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


接上篇,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();

}

4MainActivity中的调用

/****************************************************************************
****************************************************************************/
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();		
		}
    }
  
}

5native 需要修改的地方

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切换时内存释放有小量泄露还需要进一步处理。


你可能感兴趣的:(c++,cocos,java)