Android: поток прерывается с перерывами - PullRequest
3 голосов
/ 18 апреля 2011

возникли проблемы с потоком (CanvasThread), который периодически останавливается в случайных точках в моем приложении.Все остальное в приложении продолжает функционировать по мере необходимости, это просто поток, который по какой-то причине случайно блокируется и не выводит ничего нового на экран.Я заметил, что Surface.lockCanvasNative (), похоже, последняя функция, вызываемая перед блоком, а первая возвращается после.В шаблоне как таковом:

Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 26,560 msec  ____
Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 40,471 msec  ____|

Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 40,629 msec  ____
Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 54,516 msec  ____|

Это видно из трассировки ниже: traceview of frozen thread

Я использовал CanvasThread.run() ниже, если это помогает:

@Override
public void run() {

    boolean tellRendererSurfaceChanged = true;

    /*
     * This is our main activity thread's loop, we go until
     * asked to quit.
     */
    while (!mDone) {
        /*
         *  Update the asynchronous state (window size)
         */
        int w;
        int h;
        synchronized (this) {
            // If the user has set a runnable to run in this thread,
            // execute it and record the amount of time it takes to 
            // run.
            if (mEvent != null) {
                mEvent.run();
            }

            if(needToWait()) {
                while (needToWait()) {
                    try {
                        wait();
                    } catch (InterruptedException e) {

                    }
                }
            }
            if (mDone) {
                break;
            }
            tellRendererSurfaceChanged = mSizeChanged;
            w = mWidth;
            h = mHeight;
            mSizeChanged = false;
        }


        if (tellRendererSurfaceChanged) {
            mRenderer.sizeChanged(w, h);
            tellRendererSurfaceChanged = false;
        }

        if ((w > 0) && (h > 0)) {
            // Get ready to draw.
            // We record both lockCanvas() and unlockCanvasAndPost()
            // as part of "page flip" time because either may block
            // until the previous frame is complete.

            Canvas canvas = mSurfaceHolder.lockCanvas();

            if (canvas != null) {
                // Draw a frame!
                mRenderer.drawFrame(canvas);                        
                mSurfaceHolder.unlockCanvasAndPost(canvas);

                //CanvasTestActivity._isAsyncGoTime = true;    
            }
            else{
                Log.v("CanvasSurfaceView.CanvasThread", "canvas == null");
            }
        }
    }
}

Просто дайте мне знать, если я смогу предоставить любую другую полезную информацию.Я просто ищу подсказки о том, почему мой поток может блокировать на этом этапе?Заранее благодарю за любую помощь!

С тех пор я сузил блок до mSurfaceHolder.unlockCanvasAndPost(canvas); Я вставил журнал до и после этого вызова, а после не регистрируется после того, как приложение заморожено;но журнал до является последним зарегистрированным событием в этом потоке.Он также не приостанавливает и не использует пустой холст, потому что я добавлял логи и для этих экземпляров;которые не регистрируются ни разу, пока приложение не будет завершено.

Ответы [ 2 ]

3 голосов
/ 22 апреля 2011

Я с тех пор разобрался с моей проблемой. Я не уверен, почему, но потому что я случайно забыл полностью закомментировать более раннюю функцию asyncTask (), поэтому у двух было примерно одно и то же задание, и он явно пытался сделать это с одинаковыми переменными и тому подобное. Спасибо за ваши указания, но я думаю, это просто еще одна неосторожная ошибка с моей стороны.

3 голосов
/ 21 апреля 2011

Я не уверен, может ли это быть причиной, но в SurfaceHolder.lockCanvas () он предупреждает, что

Если вы вызываете это несколько раз, когда Поверхность не готова (до Callback.surfaceCreated или после Callback.surfaceDestroyed), ваши звонки будет замедлен до медленной скорости в Чтобы избежать использования процессора.

Если ноль не возвращается, эта функция внутренне удерживает замок до соответствующий вызов unlockCanvasAndPost (Canvas), предотвращение создания SurfaceView, уничтожение или изменение поверхности пока он рисуется. Это может быть более удобный, чем доступ к Поверхность прямо, так как вам не нужно сделать специальную синхронизацию с рисование нити в Callback.surfaceDestroyed.

Я не уверен, каково пороговое значение, когда процессор начинает дросселировать. Сколько ниток освежает холст?

кстати,

if(needToWait()) {
                while (needToWait()) {

является избыточным

...