問題描寫敘述
cocos2d-x游戲項目androidproject接入sdk。支付成功后,java代碼回調lua方法。產生了anr。
怎樣定位anr?
在data/anr/traces.txt文件里記錄和anr錯誤信息。能夠使用RE管理器查看該文件。
在日志信息中能夠看到回調方法中調用的cocos2d-x的音頻引擎播放音效的方法。就在這里產生了anr。我這里使用的是cocos2d-x2.1.5。
找到出問題的根源后,我把播放音效的代碼凝視了。然后再執行。就沒有產生anr了。
可是,還有一個問題又出現了...
報了一個OpenGL error,創建CCSprite也失敗了。出現這種問題通常是由於CCSpirte沒有在GL線程中創建。
主線程與GL 線程
主線程(ui thread):app啟動時創建的線程。其他線程都是該線程的子線程。主要用於更新UI的線程。
GL線程:主線程的一個子線程。主要用於更新GUI的線程。在Cocos2d-x中,會從主線程中分出一個GL線程用於畫面渲染相關的工作(為了保證畫面的流暢)。
Android下。Activity有一個runOnUiThread方法。該方法用於在主線程中運行一個任務。
注意,假設該任務比較耗時會產生anr。
方法的聲明例如以下:
public void runOnUiThread(Runnable task);
在Android下OpenGL的渲染須要與GLSurfaceView打交道。
所以Cocos2d-x封裝了一個Cocos2dxGLSurfaceView。該View是與GL線程相關的。
Cocos2dxActivity中包括了一個Cocos2dxGLSurfaceView。並提供一個runOnGLThread方法。該方法用於在GL線程中運行一個任務。
方法聲明例如以下:
public void runOnGLThread(final Runnable task);
實現上是調用了GLSurfaceView的queueEvent方法實現與GL線程通信。
實現機制還是Android下的消息輪詢。
最后,通過runOnGLThread方法,在GL線程中回調lua方法。問題就徹底攻克了。
ctx.runOnGLThread(new Runnable() { @Override public void run() { PayTools.payCallback(); //lua方法須要在GL線程中調用 } });