今天我家小管遇到一個問題,每次都是報
CCApplication* CCApplication::sharedApplication(){ CCAssert(sm_pSharedApplication, ""); return sm_pSharedApplication;}
中的ccassert(sm_pShareApplication,"")的錯誤。百度之後發現解決方案是:
Edit cocos2dxplatformandroidjniJava_org_cocos2dx_lib_Cocos2dxRenderer.cppLine 18 to:if (CCDirectorsharedDirector()->getOpenGLView()) CCApplicationapplicationDidEnterBackground();}
按照這方案來做之後,問題果然迎刃而解。可是我家小管問我,為什麼會這樣就不會閃退了呢?一時語塞,都不知道怎麼回答。然後按照修改的地方順藤摸瓜的慢慢的看上去發現
看了一下halloworld中的pro.android/jni/hallocpp/main.cpp 这里是我们cocos程序在android中的真正的入口。
jint JNI_OnLoad(JavaVMvm voidreserved) JniHelpersetJavaVM JNI_VERSION_1_4} Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv env jobject thiz jint w jint h(!CCDirector CCEGLViewview = CCEGLViewsharedOpenGLView(); view->setFrameSizew h AppDelegatepAppDelegate new AppDelegate CCApplicationrun}else ccDrawInit ccGLInvalidateStateCache CCShaderCachesharedShaderCachereloadDefaultShaders CCTextureCachereloadAllTextures CCNotificationCentersharedNotificationCenterpostNotificationEVNET_COME_TO_FOREGROUND NULL CCDirectorsetGLDefaultValues }
JNI_OnLoad(JavaVM *vm,void *reserved)会在System.loadLibrary("cocos2dcpp")中被调用,开始加载此libcocos2dcpp.so。在HalloWorldActivity 的onCreate方法开始正式构造我们的cocos世界。这里直接调用的Cocos2dxActivity的onCreate(final Bundle savedInstanceState)方法。
@Overrideprotected onCreate(final Bundle savedInstanceState)superonCreatesavedInstanceState); sContext this; mHandler Cocos2dxHandler); //新建一个cocos的消息处理器init(); //此处为cocos 的真正初始化 Cocos2dxHelper}
Cocos2dxHandler主要处理显示Dialog的消息,Cocos2dxHelper是个辅助类,我们主要看init()方法
public init() // FrameLayout ViewGroup.LayoutParams framelayout_params ViewGroup.LayoutParams(ViewGroupFILL_PARENT ViewGroup FrameLayout framelayout FrameLayout framelayoutsetLayoutParamsframelayout_params // Cocos2dxEditText layout edittext_layout_params WRAP_CONTENT Cocos2dxEditText edittext Cocos2dxEditText edittextedittext_layout_params// ...add to FrameLayoutaddViewedittext// Cocos2dxGLSurfaceView mGLSurfaceView onCreateView(); //创建了Cocos2dxGLSurfaceViewmGLSurfaceView// Switch to supported OpenGL (ARGB888) mode on emulatorisAndroidEmulatorsetEGLConfigChooser(88160setCocos2dxRenderer Cocos2dxRenderer());setCocos2dxEditText// Set framelayout as the content view setContentViewframelayout}
this.mGLSurfaceView = this.onCreateView();创建了一个Cocos2dxGLSurfaceView对象。这个Cocos2dxGLSurfaceView对象是我们cocos的进行绘制的所需要的对象。其中有一个onSurfaceCreated()方法。onSurfaceCreated():当创建GLSurfaceView时被调用,只调用一次.在这个方法中执行只发生一次的动作,比如设置OpenGL环境参数或初始化OpenGL图形对象.
onSurfaceCreated GL10 pGL10 EGLConfig pEGLConfignativeInitmScreenWidthmScreenHeight); //调用我们的main.cpp中的nativeInit方法哦mLastTickInNanoSeconds SystemnanoTime}
好了找到了nativeInit的调用的位置,我们来看看nativeInit做了什么事情。
CCDirector就是是cocos2d-x中的导演类,该类在$(sourcedir)\cocos2dx\CCDirector.cpp中实现。方法sharedDirector是类CCDirector的一个静态方法,该方法用来创建游戏中唯一的CCDirector对象,代码如下:
CCDirector CCDirectorvoid(!s_SharedDirector s_SharedDirector CCDisplayLinkDirector s_SharedDirector s_SharedDirector}
这里的CCCCDisplayLinkDirector是CCDirector的子类,方法init()做一些初始化工作:
bool CCDirector setDefaultValues //场景相关...//管理场景的数组栈 m_pobScenesStack CCArray m_pobScenesStack// 一些FPS等相关的成员变量初始化//初始化调度器对象 m_pScheduler CCScheduler//动作管理器对象 m_pActionManager CCActionManager m_pSchedulerscheduleUpdateForTargetm_pActionManager kCCPrioritySystemfalse// touchDispatcher,KeypadDispatcher,Accelerometer等对象初始化// CCPoolManager中实现了cocos2d-x CCObject对象的内存管理机制 CCPoolManagersharedPoolManagerpushtrue}
创建好导演对象后,Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit中调用了该对象的getOpenGLView方法:
该方法返回用于游戏绘制的CCEGLView,在init()中,m_pobOpenGLView复制为NULL。在Android平台下,这个CCEGLView其实没有什么作用,因为游戏都是绘制在Cocos2dxGLSurfaceView上的,因此方法Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit接着执行if分支:
CCEGLViewview);
这里同样创建了游戏中类CCEGLView的唯一实例,类在$(sourcedir)\cocos2dx\platform\android\CCEGLView.cpp中实现。接着执行
AppDelegate();CCApplication();
创建了一个类AppDelegate对象,类AppDelegate在$(sourcedir)\samples\Lua\HelloLua\Classes\AppDelegate.cpp中实现,类AppDelegate在各个平台之间共用的:
class AppDelegate:private cocos2d::CCApplication{publicvirtual~AppDelegatebool applicationDidFinishLaunching applicationDidEnterBackground applicationWillEnterForeground};
该类继承自CCApplication,注意类CCApplication是在$(sourcedir)\cocos2dx\platform\android\CCApplication.cpp中实现的,它的实现是与平台相关的。创建AppDelegate实例的工作实质就是实例化CCApplication,它的构造函数代码如下:
sm_pSharedApplication }
可是这与修改Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause()有什么关系呢?
Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause函数在Cocos2dxGLSurfaceView的handleOnPause中被调用。
handleOnPausenativeOnPause}
handleOnPause()又再Cocos2dxActivity 的OnPause()中被调用。
可是如果这个mGLSurfaceView还没有被new的时候Cocos2dxActivity被别的Activity 给挂起了,于是乎就会自动执行OnPause 方法,而此时CCApplication还没有被初始化,所以直接调用了
CCApplication();