Android:线程间歇暂停
在我的应用程序中,某个线程(CanVastThread)在随机点间歇暂停时遇到一些问题。应用程序中的所有其他内容都会根据需要继续发挥作用,只是由于某种原因,该线程会随机屏蔽,不会在屏幕上显示任何新内容。我注意到Surface.lockCanvasNative()似乎是在块之前调用的最后一个函数,在块之后返回的第一个函数。以这样的模式: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
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()) {