I am trying to draw some shapes on a SurfaceView from a stream, but nothing is displayed on the screen. I considered similar questions in people having the same problem, but none of the answers led me to a solution, suggesting a different reason in my particular case.
I created a simplified version of my code to demonstrate this problem. Rendering is handled by the RenderingTestView class, which implements a custom view obtained from SurfaceView. The rendering stream is implemented as Runnable inside the 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) {
Placing a breakpoint inside Draw() confirms that it was successfully called.
The layout file is as follows:
<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>
Overriding onDraw() in a RenderingTestView , for example:
@Override public void onDraw(Canvas canvas) { super.onDraw(canvas); Draw(canvas); }
... and calling setWillNotDraw(false) inside init_view() does produce the desired result, but I want to render from Runnable and not wait for invalidate () to call onDraw() .