Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> cocos2dx-2.X前後台切換分析,基於android平台

cocos2dx-2.X前後台切換分析,基於android平台

編輯:關於Android編程

摘自網上的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();
		}
        }


 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved