我通過添加日誌語句來查找程序凍結的行,執行了「二分查找」。我發現凍結髮生在初始啓動時,當渲染線程嘗試獲取畫布上的鎖定時。
如果我在呈現線程嘗試獲取鎖之前立即插入thread.sleep(),問題就會消失。我完全意外地發現了這一點:我在那裏插入了一條日誌語句,並且日誌語句本身造成遊戲開始工作的延遲足夠了!這是我(簡化)代碼結構和修復:
public class theview extends SurfaceView implements SurfaceHolder.Callback {
private final SurfaceHolder mSurfaceHolder;
public theview(Context context, AttributeSet attrs) {
super(context, attrs);
mSurfaceHolder = getHolder();
//(other game-initialization code omitted)
thread = new LunarThread();
public void surfaceCreated(SurfaceHolder holder) {
//(other game-resuming code omitted)
mRun=True;
thread.start();
}
class LunarThread extends Thread {
@Override
public void run() {
Canvas c=null;
while (mRun) {
try {
LunarThread.sleep(0, 1); // <---the LG G4 needs this line or the game doesn't load! Sleep duration didn't matter.
}catch(InterruptedException ignored){}
if(c==null){
LunarThread.yield();//app is still loading; wait for it.
}
try {
c = mSurfaceHolder.lockCanvas(null); // <---- this is the line where the LG G4 freezes without the above sleep()
if (c != null) {
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) doPhysics();
doDraw(c);
}
}
}
finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
的1ns的延遲很短,以至於我只是說這所有的手機。 (這應該不用說,但顯然這只是LG G4定製版Android操作系統中一個令人討厭的潛在錯誤的緩解,客戶報告說,它不會發生在其他LG手機上。這個問題分別給LG)。
如果程序崩潰了,99%的時間裏有logcat中的堆棧跟蹤,告訴你哪一行崩潰了。沒有理由對日誌進行二分查找。如果你正在增加睡眠來修復某些東西,那麼你並沒有真正修復它。花點時間找出真正的解決方案,而不是在這裏發佈惡意攻擊。 –
@GabeSechan正如我在問題中所說的那樣,它沒有提出任何例外。只是一個操作系統級別的崩潰。我記錄了避免操作系統級別崩潰的解決方法。你如何建議我進一步調試LG的Android系統函數的閉源版本中發生的崩潰,當我正確地調用該函數? – Luke