標籤:
摘自網上的android生命週期圖:
cocos2dx-2.X前後台切換分析,基於android平台:1、從後台進入前台項目的activity一般繼承自Cocos2dxActivity,看過activity生命週期的都知道onCreate,onResume等方法,這些函數是activity生命週期中最重要的函數,具體什麼時候調用,可以查看相關資料。 //剛進入遊戲和遊戲從後台回到前台會調用@Overrideprotected void onResume() {super.onResume();Log.d(TAG, "onResume+++++++++++++++++++++++");Cocos2dxHelper.onResume();this.mGLSurfaceView.onResume(); --->>}this.mGLSurfaceView.onResume(); 方法--->> @Overridepublic void onResume() {super.onResume();this.setRenderMode(RENDERMODE_CONTINUOUSLY);//使用queueEvent方法:主要是從UI線程切換到OpenGL渲染線程this.queueEvent(new Runnable() {@Overridepublic 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、 //從前台進入後台會調用過程@Overrideprotected void onPause() {super.onPause();Log.d(TAG, "onPause+++++++++++++++++++++++");Cocos2dxHelper.onPause();this.mGLSurfaceView.onPause();} //this.mGLSurfaceView.onPause();--->>@Overridepublic void onPause() {this.queueEvent(new Runnable() {@Overridepublic 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();} }
cocos2dx-2.X前後台切換分析,基於android平台