CCAssert(sm_pSharedApplication, "")导致程序闪退的原因以及解决方案

前端之家收集整理的这篇文章主要介绍了CCAssert(sm_pSharedApplication, "")导致程序闪退的原因以及解决方案前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

今天我家小管遇到一個問題,每次都是報

 
 
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()中被调用


   
   
  • onPauseonPause(); //此处被调用}

    可是如果这个mGLSurfaceView还没有被new的时候Cocos2dxActivity被别的Activity 给挂起了,于是乎就会自动执行OnPause 方法,而此时CCApplication还没有被初始化,所以直接调用

    
      
      CCApplication();
    就用引起空指针异常,程序就会闪退了。可是CCDirector::sharedDirector()->getOpenGLView() 在上文中我们看到它是和CCApplication一起初始化的,所以只要CCDirector::sharedDirector()->getOpenGLView()为真,那么我们就可以放心的使用CCApplication啦。

    猜你在找的Cocos2d-x相关文章