CCAssert(sm_pSharedApplication, "")导致程序闪退的原因以及解决方案
来源:互联网 发布:apache rewrite 配置 编辑:程序博客网 时间:2024/04/27 14:30
今天我家小管遇到一個問題,每次都是報
CCApplication* CCApplication::sharedApplication()
{
CCAssert(sm_pSharedApplication, "");
return sm_pSharedApplication;
}
中的ccassert(sm_pShareApplication,"")的錯誤。百度之後發現解決方案是:
Edit cocos2dxplatformandroidjniJava_org_cocos2dx_lib_Cocos2dxRenderer.cpp
Line 18 to:
if (CCDirector::sharedDirector()->getOpenGLView()) {
CCApplication::sharedApplication()->applicationDidEnterBackground();
}
按照這方案來做之後,問題果然迎刃而解。可是我家小管問我,為什麼會這樣就不會閃退了呢?一時語塞,都不知道怎麼回答。然後按照修改的地方順藤摸瓜的慢慢的看上去發現
看了一下halloworld中的pro.android/jni/hallocpp/main.cpp 这里是我们cocos程序在android中的真正的入口。
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JniHelper::setJavaVM(vm);
return JNI_VERSION_1_4;
}
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
{
if (!CCDirector::sharedDirector()->getOpenGLView())
{
CCEGLView *view = CCEGLView::sharedOpenGLView();
view->setFrameSize(w, h);
AppDelegate *pAppDelegate = new AppDelegate();
CCApplication::sharedApplication()->run();
}
else
{
ccDrawInit();
ccGLInvalidateStateCache();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
CCTextureCache::reloadAllTextures();
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
CCDirector::sharedDirector()->setGLDefaultValues();
}
}
JNI_OnLoad(JavaVM *vm ,void *reserved)会在System.loadLibrary("cocos2dcpp")中被调用,开始加载此libcocos2dcpp.so。在HalloWorldActivity 的onCreate方法开始正式构造我们的cocos世界。这里直接调用的Cocos2dxActivity的onCreate(final Bundle savedInstanceState)方法。
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sContext = this;
this.mHandler = new Cocos2dxHandler(this); //新建一个cocos的消息处理器
this.init(); //此处为cocos 的真正初始化
Cocos2dxHelper.init(this, this);
}
Cocos2dxHandler主要处理显示Dialog的消息,Cocos2dxHelper是个辅助类,我们主要看init()方法
public void init() {
// FrameLayout
ViewGroup.LayoutParams framelayout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
FrameLayout framelayout = new FrameLayout(this);
framelayout.setLayoutParams(framelayout_params);
// Cocos2dxEditText layout
ViewGroup.LayoutParams edittext_layout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Cocos2dxEditText edittext = new Cocos2dxEditText(this);
edittext.setLayoutParams(edittext_layout_params);
// ...add to FrameLayout
framelayout.addView(edittext);
// Cocos2dxGLSurfaceView
this.mGLSurfaceView = this.onCreateView(); //创建了Cocos2dxGLSurfaceView
// ...add to FrameLayout
framelayout.addView(this.mGLSurfaceView);
// Switch to supported OpenGL (ARGB888) mode on emulator
if (isAndroidEmulator())
this.mGLSurfaceView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
this.mGLSurfaceView.setCocos2dxEditText(edittext);
// Set framelayout as the content view
setContentView(framelayout);
}
this.mGLSurfaceView = this.onCreateView();创建了一个Cocos2dxGLSurfaceView对象。这个Cocos2dxGLSurfaceView对象是我们cocos的进行绘制的所需要的对象。其中有一个onSurfaceCreated()方法。onSurfaceCreated():当创建GLSurfaceView时被调用,只调用一次.在这个方法中执行只发生一次的动作,比如设置OpenGL环境参数或初始化OpenGL图形对象.
@Override
public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) {
Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight); //调用我们的main.cpp中的nativeInit方法哦
this.mLastTickInNanoSeconds = System.nanoTime();
}
好了找到了nativeInit的调用的位置,我们来看看nativeInit做了什么事情。
CCDirector就是是cocos2d-x中的导演类,该类在$(sourcedir)\cocos2dx\CCDirector.cpp中实现。方法sharedDirector是类CCDirector的一个静态方法,该方法用来创建游戏中唯一的CCDirector对象,代码如下:
CCDirector* CCDirector::sharedDirector(void)
{
if (!s_SharedDirector)
{
s_SharedDirector = new CCDisplayLinkDirector();
s_SharedDirector->init();
}
return s_SharedDirector;
}
这里的CCCCDisplayLinkDirector是CCDirector的子类,方法init()做一些初始化工作:
bool CCDirector::init(void)
{
setDefaultValues();
//场景相关
...
...
//管理场景的数组栈
m_pobScenesStack = new CCArray();
m_pobScenesStack->init();
// 一些FPS等相关的成员变量初始化
...
...
//初始化调度器对象
m_pScheduler = new CCScheduler();
//动作管理器对象
m_pActionManager = new CCActionManager();
m_pScheduler->scheduleUpdateForTarget(m_pActionManager, kCCPrioritySystem, false);
// touchDispatcher,KeypadDispatcher,Accelerometer等对象初始化
...
...
// CCPoolManager中实现了cocos2d-x CCObject对象的内存管理机制
CCPoolManager::sharedPoolManager()->push();
return true;
}
创建好导演对象后,Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit中调用了该对象的getOpenGLView方法:
该方法返回用于游戏绘制的CCEGLView,在init()中,m_pobOpenGLView复制为NULL。在Android平台下,这个CCEGLView其实没有什么作用,因为游戏都是绘制在Cocos2dxGLSurfaceView上的,因此方法Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit接着执行if分支:
CCEGLView *view = CCEGLView::sharedOpenGLView();
view->setFrameSize(w, h);
这里同样创建了游戏中类CCEGLView的唯一实例,类在$(sourcedir)\cocos2dx\platform\android\CCEGLView.cpp中实现。接着执行
AppDelegate *pAppDelegate = new AppDelegate();
CCApplication::sharedApplication()->run();
创建了一个类AppDelegate对象,类AppDelegate在$(sourcedir)\samples\Lua\HelloLua\Classes\AppDelegate.cpp中实现,类AppDelegate在各个平台之间共用的:
class AppDelegate : private cocos2d::CCApplication
{
public:
AppDelegate();
virtual ~AppDelegate();
virtual bool applicationDidFinishLaunching();
virtual void applicationDidEnterBackground();
virtual void applicationWillEnterForeground();
};
该类继承自CCApplication,注意类CCApplication是在$(sourcedir)\cocos2dx\platform\android\CCApplication.cpp中实现的,它的实现是与平台相关的。创建AppDelegate实例的工作实质就是实例化CCApplication,它的构造函数代码如下:
CCApplication::CCApplication()
{
CCAssert(! sm_pSharedApplication, "");
sm_pSharedApplication = this;
}
可是这与修改Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause()有什么关系呢?
Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause函数在Cocos2dxGLSurfaceView的handleOnPause中被调用。
public void handleOnPause() {
Cocos2dxRenderer.nativeOnPause();
}
handleOnPause()又再Cocos2dxActivity 的OnPause()中被调用。
@Override
protected void onPause() {
super.onPause();
Cocos2dxHelper.onPause();
this.mGLSurfaceView.onPause(); //此处被调用哦
}
可是如果这个mGLSurfaceView还没有被new的时候Cocos2dxActivity被别的Activity 给挂起了,于是乎就会自动执行OnPause 方法,而此时CCApplication还没有被初始化,所以直接调用了
CCApplication::sharedApplication()->applicationDidEnterBackground();
- CCAssert(sm_pSharedApplication, "")导致程序闪退的原因以及解决方案
- ios 闪退的原因及解决方案
- 程序闪退出现的原因
- OOM内存溢出错误,导致程序闪退的解决办法
- 修改Activity的继承类导致程序闪退
- android sdk 环境变量配置遇到无效路径的原因,也导致了SDK Manager 闪退
- ARC模式下,程序闪退原因
- 导致ImportError: No module named 'xxx'问题的两种原因以及解决方案
- GCD导致死锁的原因和解决方案
- 多线程导致的iOS闪退分析
- 关于ios使用线程导致程序不规律的闪退问题解决
- 那些导致程序抽风的神秘原因
- 导致vc程序崩溃的原因
- 我的程序退不出去的原因
- android app 闪退的原因
- tomcat启动闪退的原因之一
- iOS 应用闪退的原因
- Tomcat启动闪退的原因
- 欢迎使用CSDN-markdown编辑器
- mybatis--动态SQL
- apt-get install 报Failed to fetch http
- spring中ResourceBundleMessageSource与ReloadableResourceBundleMessageSource查找资源的区别
- 初学Swift,初步了解
- CCAssert(sm_pSharedApplication, "")导致程序闪退的原因以及解决方案
- 学习iOS的第一天
- Java StringBuffer.delete()方法
- JAVAScrpit中由判断图片目录是否存在引申的关于文件的判断
- Spring注解@Controller @RequestMapping详解
- iOS 使用代理实现页面传值
- Android Studio使用技能分享(2)--全面提升你的开发效率,让你运指如飞
- pip Could not fetch URL的解决方案
- 深入浅出 消息队列 ActiveMQ