編輯:關於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();
}
}
Android特效專輯(六)——仿QQ聊天撒花特效,無形裝逼,最為致命
Android特效專輯(六)——仿QQ聊天撒花特效,無形裝逼,最為致命 日後我所寫的特效專輯也會以一添加在這個專欄上,今天寫的這個特效,是關於聊天
實現輪轉廣告帶底部指示的自定義ViewPager控件
有許多博客和開源項目都致力於這項工作,但是他們的工作大都是為了制作類似於啟動頁的效果,ViewPager全屏顯示,或者自己可操作的屬性難以滿足要求,因此我想把ViewPa
Android學習筆記4 Activity的生命周期
1 activity的聲明周期 安卓程序的最重要三個狀態為Resumed/Paused/Stopped, 絕大多數時間程序都會在這3個狀態間切換. 安卓程
Android fragment(片段)構建靈活的UI
在以支持多種屏幕尺寸為目標設計應用時,您可以在不同的布局配置中重復使用您的fragment從而根據可用的屏幕空間優化用戶體驗。例如,在手機設備上,由於采用單窗格用戶界面,