android - 使用 SurfaceView 替换 View 以在 UI 线程之外进行绘制

标签 android android-view

除非取消注释 while (!done) 行(和右括号),否则以下程序无法运行。

你明白为什么吗?为什么不能要求线程只运行一次绘图代码?

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder holder;
    private MyThread myThread;
    private boolean hasSurface;

    protected float x, y;
    protected Paint paint;

    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);

        holder = getHolder();
        holder.addCallback(this);
        hasSurface = false;

        paint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.SUBPIXEL_TEXT_FLAG);
        paint.setColor(Color.RED);
    }

    public void resume() {
        if (myThread == null) {
            myThread = new MyThread();

            if (hasSurface == true)
                myThread.start();
        }
    }

    public void pause() {
        if (myThread != null) {
            myThread.requestExitAndWait();
            myThread = null;
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        hasSurface = true;
        if (myThread != null)
            myThread.start();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;
        pause();
    }

    public void surfaceChanged(SurfaceHolder holder, int format,
                               int w, int h) {
        if (myThread != null)
            myThread.onWindowResize(w, h);
    }

    @Override public boolean onTouchEvent(MotionEvent event) {
        x = event.getX();
        y = event.getY();
        postInvalidate();
        return true;
    }

    //************************************************
    class MyThread extends Thread {
        private int width, height;

        private boolean done;

        MyThread() {
            super();
            done = false;
        }

        @Override
        public void run() {
            SurfaceHolder surfaceHolder = holder;

            // while (!done) { --- We wish to update just once.

                Canvas canvas = surfaceHolder.lockCanvas();

                canvas.drawARGB(255, 0, 0, 128);
                canvas.drawCircle(x, y, 5.0f, paint);

                surfaceHolder.unlockCanvasAndPost(canvas);
                }
            // }
        }

        public void requestExitAndWait() {
            done = true;
            try {
                join();
            } catch (InterruptedException ex) { }
        }

        public void onWindowResize(int w, int h) {
            width = w;
            height = h;
        }
    }
}

这是 Activity :

public class MyActivity extends Activity {

    MySurfaceView mySurfaceView;

    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mySurfaceView = (MySurfaceView) findViewById(R.id.mySurfaceView);
    }

    @Override protected void onResume() {
        super.onResume();
        mySurfaceView.resume();
    }

    @Override protected void onPause() {
        super.onPause();
        mySurfaceView.pause();
    }
}

..这是布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">
   <.MySurfaceView
       android:id="@+id/mySurfaceView"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"/>
</FrameLayout>

最佳答案

给你

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    ...

    class MyThread extends Thread {

        boolean update = false;

        @Override
        public void run() {
            SurfaceHolder surfaceHolder = holder;

            while (!done) {

                if(update) {
                    Canvas canvas = surfaceHolder.lockCanvas();

                    canvas.drawARGB(255, 0, 0, 128);
                    canvas.drawCircle(x, y, 5.0f, paint);

                    surfaceHolder.unlockCanvasAndPost(canvas);
                    update = false;
                }
            }
        }
    }

    public void requestUpdate() {
        update = true;
    }
}

无论何时发生变化,只需调用 requestUpdate();

关于android - 使用 SurfaceView 替换 View 以在 UI 线程之外进行绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18240420/

相关文章:

android - 如何计算Android应用程序的功耗?

android - 将 View 与另一个 View 的左右位置对齐,约束布局?

android - 如何获取不在Acitivty自身布局上的布局组件

安卓:alertDialog 不工作

java - Java/Android 中的 EA Async.Init() 错误

Android Wear Overlay 传递触摸事件

android - setAlpha 和 setImageAlpha 的区别

java - Android - findViewById() 和动态设置 ID

android - 在带有覆盖的背景图像上方渲染组件

android - React-native 访问设备摄像头? (特别是安卓)