本文對於runOnGLThread方法的分析主要目的是為了幫助我的課程“拇指接龍游戲”學員更好地理解EasyNDK這個開源框架的使用。借助於這個框架,實現Android JAVA端與Cococ2d-x C++端交互,以及iOS Objective-C端與Cococ2d-x C++端交互將變得異常容易----極大地減少了相關的JNI編程與Objecive-C編程的代碼量。但是,在EasyNDK的Android版本示例中在Java主Activity端存在如下代碼段:
public void ChangeSomethingInCocos() {
this.runOnGLThread(new Runnable()
{
@Override
public void run()
{
AndroidNDKHelper.SendMessageWithParameters("ChangeLabelSelector", null);
}
});
}
在android中經常需要用到異步操作,Thread+Handler方式比較繁瑣(當然功能也最為強大),而AsyncTask只能執行一次,很多需求不能滿足(有關AsyncTask用法,請參考我引用的另外一篇博客)。
此時,我們可以試試Activity提供的另外一種簡單的方法runOnUiThread,runOnUiThread可以幫助你在線程中執行UI更新操作。
以下為線程中使用runOnUiThread方法的框架代碼:
MyActivity.this. runOnUiThread(new Runnable() {
@Override
public void run()
{
// refresh ui 的操作代碼
}
});
這里需要注意:runOnUiThread是Activity中的方法,在我們的工作線程中需要告訴系統是哪個Activity調用,所以前面顯式地指明Activity。
下面為runOnUiThread的宏觀代碼:
public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } }
從代碼可以看到,runOnUiThread首先判斷是否是UI線程,不是的話就post,如果是的話就正常運行該線程。只要經過主線程中的Handler.post或者postDelayed處理,線程Runnable都可以被加入到UI主線程的消息循環中,並為主線程的Handler所檢索並調用。有關的Handler運行原理,請參考我引用的其他幾篇博客文章。
值得注意的是,本節中的runOnUiThread方法適合於從子線程中更新普通Android View內容時調用。但是,當我們在Android下進行OpenGL ES開發時,也就是本文關注的cocos2d-x開發時,需要使用另一個方法,即下文要討論的runOnGLThread。
二、Cocos2d-x編程中的runOnGLThread方法
cocos2d-x開發中,一旦涉及到Android平台移植自然要與Cocos2dxActivity這個東西打交道。Cocos2dxActivity是cocos2d-x開發團隊的成果,它是一個抽象類,具體形式如下:
public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener {//...}
我們知道,cocos2d-x是運行於OpenGL平台的。Android平台下進行OpenGL開發要與一個特殊View--GLSurefaceView打交道。GLSurefaceView要使用它自己的渲染器(Render)進行圖形渲染,這個Render是運行於一個獨立的區別於主GUI線程的子線程上的。
接下來,我們跟蹤觀察一下接口Cocos2dxHelperListener的定義(它隱藏於文件Cocos2dxHelper.java中):
public static interface Cocos2dxHelperListener
{
public void showDialog(final String pTitle, final String pMessage);
public void showEditTextDialog(final String pTitle, final String pMessage, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength);
public void runOnGLThread(final Runnable pRunnable);
}
其中的前兩個方法與Cocos2d-x中顯然對話框與文本框有關,在此我們省略有關討論,而只專注於方法runOnGLThread。