gpt4 book ai didi

Android:线程间歇性暂停

转载 作者:太空宇宙 更新时间:2023-11-03 12:42:21 25 4
gpt4 key购买 nike

在我的应用程序中间歇性地在随机点暂停的线程 (CanvasThread) 遇到一些问题。应用程序中的所有其他内容都会根据需要继续运行,只是这个线程出于某种原因随机阻塞并且不会在屏幕上绘制任何新内容。我注意到 Surface.lockCanvasNative() 似乎是 block 之前调用的最后一个函数,并且是之后返回的第一个函数。在这样的模式中:

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 ____|

下面的跟踪 View 很明显: 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");
}
}
}
}

如果我能提供任何其他有用的信息,请告诉我。我只是在寻找关于为什么我的线程此时可能会阻塞的线索?提前感谢您的帮助!

我已经将 block 缩小到 mSurfaceHolder.unlockCanvasAndPost(canvas); 我在这个调用之前和之后插入了一个日志,并且在应用程序卡住后不记录之后的日志;但之前的日志是该线程上最后记录的事件。它也没有暂停或使用空 Canvas ,因为我也为这些实例输入了日志;在应用程序完成之前甚至不会记录一次。

最佳答案

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

If you call this repeatedly when the Surface is not ready (before Callback.surfaceCreated or after Callback.surfaceDestroyed), your calls will be throttled to a slow rate in order to avoid consuming CPU.

If null is not returned, this function internally holds a lock until the corresponding unlockCanvasAndPost(Canvas) call, preventing SurfaceView from creating, destroying, or modifying the surface while it is being drawn. This can be more convenient than accessing the Surface directly, as you do not need to do special synchronization with a drawing thread in Callback.surfaceDestroyed.

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

顺便说一句,

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

是多余的

关于Android:线程间歇性暂停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5707303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com