SurfaceView显示为空,没有任何渲染

我试图从一个线程中将一些形状绘制到SurfaceView上,但没有任何东西被渲染到屏幕上。 我有同样问题的人看过类似的问题,但没有一个答案让我找到了解决方案,在我的具体案例中提出了不同的原因。

我已经创建了一个简化版本的代码来演示这个问题。 渲染由RenderingTestView类处理,该类实现从SurfaceView派生的自定义视图。 渲染线程在RenderingTestView中实现为Runnable:

package com.example.renderingtest.app; import android.content.Context; import android.graphics.*; import android.os.Build; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; public class RenderingTestView extends SurfaceView { private SurfaceHolder holder; private Paint paint; private boolean surfaceCreated = false; private Thread videoThread; public RenderingTestView(Context context) { super(context); init_view(context); } public RenderingTestView(Context context, AttributeSet attrs) { super(context, attrs); init_view(context); } public RenderingTestView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init_view(context); } private void init_view(Context context) { if (Build.VERSION.SDK_INT >= 11) setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null); paint = new Paint(); paint.setColor(Color.RED); holder = getHolder(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { surfaceCreated = true; videoThread = new Thread(videoRunnable); videoThread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // do nothing } @Override public void surfaceDestroyed(SurfaceHolder holder) { surfaceCreated = false; } }); } private Runnable videoRunnable = new Runnable() { @Override public void run() { Thread.currentThread().setPriority(Thread.NORM_PRIORITY); while (true) { if (!surfaceCreated || !holder.getSurface().isValid()) continue; Canvas c = holder.lockCanvas(null); try { synchronized (holder) { if (c != null) Draw(c); } } finally { if (c != null) holder.unlockCanvasAndPost(c); } } } }; protected void Draw(Canvas canvas) { canvas.drawCircle(0, 0, 100, paint); } } 

Draw()放置一个断点,确认它已被成功调用。

布局文件如下所示:

    

RenderingTestView覆盖onDraw() ,如下所示:

 @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); Draw(canvas); } 

…并且在init_view()中调用setWillNotDraw(false)确实产生了所需的输出,但是我想从Runnable内部渲染而不是等待invalidate()来生成对onDraw()的调用。

经过进一步测试,我发现问题是由以下代码引起的:

 if (Build.VERSION.SDK_INT >= 11) setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null); 

事实certificate,如上所述调用setLayerType()以某种方式阻止SurfaceView将任何内容渲染到Canvas ,并且在任何情况下都是不必要的,因为SurfaceView渲染总是在软件中执行。 当我第一次测试我的绘制调用时,我使用的是常规View而不是SurfaceView ,并且从那里inheritance了违规行。