博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2dx-2.X前后台切换分析,基于android平台
阅读量:4216 次
发布时间:2019-05-26

本文共 5296 字,大约阅读时间需要 17 分钟。

摘自网上的android生命周期图:

cocos2dx-2.X前后台切换分析,基于android平台:1、从后台进入前台项目的activity一般继承自Cocos2dxActivity,看过activity生命周期的都知道onCreate,onResume等方法,这些函数是activity生命周期中最重要的函数,具体什么时候调用,可以查看相关资料。        //刚进入游戏和游戏从后台回到前台会调用	@Override	protected void onResume() {		super.onResume();		Log.d(TAG, "onResume+++++++++++++++++++++++");		Cocos2dxHelper.onResume();		this.mGLSurfaceView.onResume(); --->>	}	this.mGLSurfaceView.onResume(); 方法--->>        @Override	public void onResume() {		super.onResume();				this.setRenderMode(RENDERMODE_CONTINUOUSLY);		//使用queueEvent方法:主要是从UI线程切换到OpenGL渲染线程		this.queueEvent(new Runnable() {			@Override			public void run() {			        				Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnResume();			}		});	}	------>>>	public void handleOnResume() {	        //private static native void nativeOnResume();		//调用了一个native方法,在C++端实现		Cocos2dxRenderer.nativeOnResume();	}        //C++端的实现在Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp文件中:	JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnResume() {				//做个标记(1)这里和我要在下面说的一点有关****		if (CCDirector::sharedDirector()->getOpenGLView()) {		    CCApplication::sharedApplication()->applicationWillEnterForeground();		}        }	// this function will be called when the app is active again	//进入前台,我们可以在这里做一些处理	void AppDelegate::applicationWillEnterForeground()	{	    CCDirector::sharedDirector()->startAnimation();	    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();	}	2、 //从前台进入后台会调用过程	@Override	protected void onPause() {		super.onPause();		Log.d(TAG, "onPause+++++++++++++++++++++++");		Cocos2dxHelper.onPause();		this.mGLSurfaceView.onPause();	}        //this.mGLSurfaceView.onPause();--->>	@Override	public void onPause() {		this.queueEvent(new Runnable() {			@Override			public void run() {				Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnPause();			}		});				this.setRenderMode(RENDERMODE_WHEN_DIRTY);				//super.onPause();	}	---->>>mCocos2dxRenderer.handleOnPause:	public void handleOnPause() {		Cocos2dxRenderer.nativeOnPause();	}        ----->>>native方法,调用C++端的函数:	private static native void nativeOnPause();	//C++端的实现在Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp文件中:	  JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause() {	  //进入后台        CCApplication::sharedApplication()->applicationDidEnterBackground();        CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_BACKGROUND, NULL);    }    // This function will be called when the app is inactive. When comes a phone call,it's be invoked too    //进入后台,我们可以在这里做一些处理。	void AppDelegate::applicationDidEnterBackground()	{	    CCDirector::sharedDirector()->stopAnimation();	    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();	}3、我的一点疑惑(已解决)从activity生命周期中我们看到,在第一次进入游戏中时也会调用onResume方法,如果这样,那我们就不能认为调用applicationWillEnterForeground方法的时机是从后台进入前台,如果这样我们在处理游戏从后台进入前台时,就需要注意这个问题。其实,第一次进入游戏applicationWillEnterForeground方法是不会调用的,我们可以不用管上面我说的那个问题。至于为什么,下面分析:3.1、在activity中的onResume方法和Cocos2dxRenderer类中的onSurfaceCreated方法中加入log日志,看下两个地方的执行顺序:        @Override	//onSurfaceCreated在surface创建时调用,在这里调用nativeInit方法进行一些初始化。	//具体整个过程,可以查看cocos2dx启动过程相关的资料。	public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) {		Log.d("", "onSurfaceCreated+++++++++++");		Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);		this.mLastTickInNanoSeconds = System.nanoTime();	}	--->>>	void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)	{	    	    if (!CCDirector::sharedDirector()->getOpenGLView())	    {	        //这里创建才创建CCEGLView,第二个标记(2)*****		CCEGLView *view = CCEGLView::sharedOpenGLView();		view->setFrameSize(w, h);		AppDelegate *pAppDelegate = new AppDelegate();		CCApplication::sharedApplication()->run();	    }	    else	    {	        //其实这里我有一点疑问?就是这个分支什么时候会被执行,我试了很多次,都没有看到什么时候执行。		//有待以后学习。		ccGLInvalidateStateCache();		CCShaderCache::sharedShaderCache()->reloadDefaultShaders();		ccDrawInit();		CCTextureCache::reloadAllTextures();		CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_FOREGROUND, NULL);		CCDirector::sharedDirector()->setGLDefaultValues(); 	    }	}	activity中的onResume方法和Cocos2dxRenderer类中的onSurfaceCreated方法的执行顺序:看下面的输出信息就可以清楚的知道,onResume方法先执行而onSurfaceCreated方法后执行。05-21 16:03:32.520: D/Cocos2dxActivity(7953): onResume+++++++++++++++++++++++  05-21 16:03:32.740: D/(7953): onSurfaceCreated+++++++++++还记的我们做过的(1)和(2)两个标记吗?标记(1):看到这里大家应该明白了吧,这里对是否进入applicationWillEnterForeground函数加了一个判断CCDirector::sharedDirector()->getOpenGLView()即CCEGLView是否存在,按照上面的说明在 onSurfaceCreated -->> Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit  -->>--->> CCEGLView *view = CCEGLView::sharedOpenGLView() 即在nativeInit方法中才创建CCEGLView类的实例,根据上面说的执行顺序,onResume方法在onSurfaceCreated方法之前执行,就意味着在nativeInit方法之前执行,同样意味着第一次进入游戏时,因为CCDirector::sharedDirector()->getOpenGLView()方法返回NULL,因为还没有实例化,所以applicationWillEnterForeground方法并不会执行。而当游戏从后台切换到前台时,CCDirector::sharedDirector()->getOpenGLView()方法返回已经构造的实例变量,所以可以进入applicationWillEnterForeground函数。JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnResume() {				//做个标记(1)这里和我要在下面说的一点有关****		if (CCDirector::sharedDirector()->getOpenGLView()) {		    CCApplication::sharedApplication()->applicationWillEnterForeground();		}        }

你可能感兴趣的文章
专利 | 一种基于深度学习的车载CAN总线入侵检测方法
查看>>
VCU解决方案及核心L9788复杂驱动功能安全审计启动
查看>>
助力“探月工程”的单元测试工具可10倍提升测试效率
查看>>
构建实时数仓 - 当 TiDB 偶遇 Pravega
查看>>
TiDB 容器化部署面面观丨「能量钛」圆桌论坛回顾
查看>>
TiDB 在网易游戏的应用实践
查看>>
迁移实战:Discourse 从 PostgreSQL 到 MySQL 到 TiDB丨AskTUG 论坛背后的故事
查看>>
TiDB Operator 源码阅读 (四) 组件的控制循环
查看>>
TiDB 5.1 发版,打造更流畅的企业级数据库体验
查看>>
2020-11-04
查看>>
OC笔记NSDate
查看>>
求两个分数的加减乘除,并比较大小
查看>>
day1: Objective-C概述、面向对象编程、类和对象、实例变量操作
查看>>
day2:实例变量可见度、方法、setter、getter
查看>>
day3: 继承、初始化方法、便利构造器
查看>>
day4_1: NSString 和 NSMutableString 的使用
查看>>
day4_2: 数组NSArray NSMutableArray、值对象NSNumber、NSValue
查看>>
day5: 字典、集、数组排序:字典类、集合类、数组数组排序、字典、集合的快速遍历、数组排序
查看>>
day6: Block、数组高级:Block语法、Block使用、Block实现数组排序
查看>>
day8: 属性、点语法、KVC
查看>>