Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:线程间歇暂停_Android_Multithreading_Android Canvas_Surfaceview_Trace - Fatal编程技术网

Android:线程间歇暂停

Android:线程间歇暂停,android,multithreading,android-canvas,surfaceview,trace,Android,Multithreading,Android Canvas,Surfaceview,Trace,在我的应用程序中,某个线程(CanVastThread)在随机点间歇暂停时遇到一些问题。应用程序中的所有其他内容都会根据需要继续发挥作用,只是由于某种原因,该线程会随机屏蔽,不会在屏幕上显示任何新内容。我注意到Surface.lockCanvasNative()似乎是在块之前调用的最后一个函数,在块之后返回的第一个函数。以这样的模式: Surface.lockCanvasNative (Landroid/graphics/Rect)Landroid/graphics/Canvas; @ 26,5

在我的应用程序中,某个线程(CanVastThread)在随机点间歇暂停时遇到一些问题。应用程序中的所有其他内容都会根据需要继续发挥作用,只是由于某种原因,该线程会随机屏蔽,不会在屏幕上显示任何新内容。我注意到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  ____|
这在下面的跟踪视图中很明显:

我一直在使用下面的
canvathread.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)我在这次通话之前和之后插入了一个日志,之后的一个在app冻结后不会被记录;但之前的日志是此线程上最后记录的事件。它也没有暂停或使用空画布,因为我也为这些实例添加了日志;在应用程序完成之前,它们甚至不会被记录一次。

我不确定这是否是原因,但在SurfaceHolder.lockCanvas()下,它警告说

如果您在 表面未准备好(之前) Callback.surfaceCreated或之后 回拨。surfaceDestroyed),您的呼叫 将在中被限制为慢速 以避免消耗CPU

如果未返回null,则此函数 在内部保持一个锁,直到 相应的 解锁canvasandpost(Canvas)调用, 防止SurfaceView创建, 破坏或修改表面 在画的时候。这可能是 比访问 表面直接,因为你不需要 使用 拉丝 Callback.surfaceDestroyed

我不确定CPU开始节流时的阈值是多少。有多少线程正在刷新画布

顺便说一句


是多余的

我已经解决了我的问题。我不知道为什么,但因为我不小心忘了完全注释掉前面的asyncTask(),因此有两个执行大致相同的任务,显然很难使用相同的变量这样做。谢谢你的指点,但我想这只是我又一个粗心的错误。

是的,在这种情况下,如果(needToWat())
,我可以省略
。我已经调查过了,并且记录了所有异常的表面活动(创建、销毁、暂停等等),在冻结期间没有任何异常发生,除了unlockCanvasAndPost()实际上没有解锁画布并将其发布到屏幕上。就它在相应的
解锁canvasandpost(Canvas)
之前一直保持锁定而言,这只是常识,不是吗?这只是防止在锁定和解锁之间进行操作。这并不意味着在调用lock解锁时lock不会解锁它?
if(needToWait()) {
                while (needToWait()) {