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