SurfaceView显示为空,没有被渲染 [英] SurfaceView appears empty, nothing being rendered
问题描述
我试图从一个线程中绘制一些形状拖到一个SurfaceView,但没有被渲染到屏幕上。我已经用有同样的问题让人看了类似的问题,但没有答案的,导致我的解决方案,这在我的具体情况不同的原因。
I'm trying to draw some shapes onto a SurfaceView from within a thread, but nothing is being rendered to the screen. I've looked at similar questions by people having the same problem, but none of the answers have led me to a solution, suggesting a different cause in my particular case.
我已经建立了我code,以说明问题的简化版本。渲染是由RenderingTestView类,它实现从SurfaceView派生的自定义视图处理。渲染线程是作为一个Runnable内RenderingTestView:
I've created a simplified version of my code to demonstrate the problem. Rendering is handled by the RenderingTestView class, which implements a custom view derived from SurfaceView. The rendering thread is implemented as a Runnable inside RenderingTestView:
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);
}
}
里面放置断点绘制()
确认它被成功调用。
布局文件看起来是这样的:
The layout file looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.example.renderingtest.app.RenderingTest" android:background="#000000">
<com.example.renderingtest.app.RenderingTest
android:id="@+id/renderingTestView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" android:layout_alignParentTop="true"/>
</RelativeLayout>
重写的onDraw()
在 RenderingTestView
,就像这样:
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Draw(canvas);
}
......,并呼吁 setWillNotDraw(假)
在 init_view()
事实上确实产生所需的输出,但我想从里面的Runnable来呈现,而不是等待无效()来产生一个呼叫的onDraw()
。
... and calling setWillNotDraw(false)
inside init_view()
does in fact produce the desired output, but I want to render from inside the Runnable rather than wait for invalidate() to produce a call to onDraw()
.
推荐答案
进一步测试后,我发现这个问题是由以下code引起的:
After further testing, I've discovered the problem is caused by the following code:
if (Build.VERSION.SDK_INT >= 11)
setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null);
原来调用 setLayerType()
如上莫名其妙prevents SurfaceView
从渲染任何东西到画布
,并在任何情况下不必要的,因为 SurfaceView
渲染总是在软件中执行。当第一次测试我的绘制调用我使用的是普通的查看
而非 SurfaceView
,以及违规结转线从。
It turns out calling setLayerType()
as above somehow prevents SurfaceView
from rendering anything onto the Canvas
, and is in any case unnecessary since SurfaceView
rendering is always performed in software. When first testing my draw calls I was using a regular View
rather than a SurfaceView
, and the offending lines were carried over from that.
这篇关于SurfaceView显示为空,没有被渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!