与SurfaceView更换视图中绘制比UI线程其他 [英] Replacing View with SurfaceView to draw on other than the UI Thread

查看:246
本文介绍了与SurfaceView更换视图中绘制比UI线程其他的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的程序不会,除非该行的工作而(!完成)(和右括号)的注释。

你明白为什么?为什么不能让线程运行绘图code只有一次?

 公共类MySurfaceView扩展SurfaceView实现SurfaceHolder.Callback {    私人SurfaceHolder持有人;
    私人MyThread的MyThread的;
    私人布尔hasSurface;    保护浮球X,Y;
    保护涂料粉刷;    公共MySurfaceView(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);        支架= getHolder();
        holder.addCallback(本);
        hasSurface = FALSE;        油漆=新的油漆(Paint.ANTI_ALIAS_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
        paint.setColor(Color.RED);
    }    公共无效简历(){
        如果(MyThread的== NULL){
            MyThread的=新MyThread的();            如果(hasSurface ==真)
                myThread.start();
        }
    }    公共无效暂停(){
        如果(MyThread的!= NULL){
            myThread.requestExitAndWait();
            MyThread的= NULL;
        }
    }    公共无效surfaceCreated(SurfaceHolder持有人){
        hasSurface = TRUE;
        如果(MyThread的!= NULL)
            myThread.start();
    }    公共无效surfaceDestroyed(SurfaceHolder持有人){
        hasSurface = FALSE;
        暂停();
    }    公共无效surfaceChanged(SurfaceHolder架,INT格式,
                               诠释W,INT高){
        如果(MyThread的!= NULL)
            myThread.onWindowResize(W,H);
    }    @覆盖公共布尔onTouchEvent(MotionEvent事件){
        X = event.getX();
        Y = event.getY();
        postInvalidate();
        返回true;
    }    // ************
    类MyThread的继承Thread {
        私人诠释宽度,高度;        私人布尔做的;        MyThread的(){
            超();
            做= FALSE;
        }        @覆盖
        公共无效的run(){
            SurfaceHolder surfaceHolder =持有人;            //而(!完成){---我们希望只更新一次。                帆布帆布= surfaceHolder.lockCanvas();                canvas.drawARGB(255,0,0,128);
                canvas.drawCircle(X,Y,5.0F,油漆);                surfaceHolder.unlockCanvasAndPost(画布);
                }
            //}
        }        公共无效requestExitAndWait(){
            做= TRUE;
            尝试{
                加入();
            }赶上(InterruptedException的前){}
        }        公共无效onWindowResize(INT W,INT高){
            宽度= W;
            高度= H;
        }
    }
}

下面是活动:

 公共类MyActivity延伸活动{    MySurfaceView mySurfaceView;    @覆盖公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        mySurfaceView =(MySurfaceView)findViewById(R.id.mySurfaceView);
    }    @覆盖保护无效onResume(){
        super.onResume();
        mySurfaceView.resume();
    }    @覆盖保护无效的onPause(){
        super.onPause();
        mySurfaceView.pause();
    }
}

..这里是布局

 <?XML版本=1.0编码=UTF-8&GT?;
<的FrameLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
   机器人:layout_width =FILL_PARENT
   机器人:layout_height =FILL_PARENT>
   < .MySurfaceView
       机器人:ID =@ + ID / mySurfaceView
       机器人:layout_width =FILL_PARENT
       机器人:layout_height =FILL_PARENT/>
< /&的FrameLayout GT;


解决方案

有你去

 公共类MySurfaceView扩展SurfaceView实现SurfaceHolder.Callback {    ...    类MyThread的继承Thread {        布尔更新=假的;        @覆盖
        公共无效的run(){
            SurfaceHolder surfaceHolder =持有人;            而(!完成){                如果(更新){
                    帆布帆布= surfaceHolder.lockCanvas();                    canvas.drawARGB(255,0,0,128);
                    canvas.drawCircle(X,Y,5.0F,油漆);                    surfaceHolder.unlockCanvasAndPost(画布);
                    更新=假的;
                }
            }
        }
    }    公共无效requestUpdate(){
        更新= TRUE;
    }
}

和东西时被更改,只需调用requestUpdate();

The following program does not work unless the line while (!done) (and the closing bracket) are uncommented.

Do you understand why? Why is it not possible to ask the thread to run the drawing code just once?

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;
        }
    }
}

Here is the 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();
    }
}

.. and here is the layout

<?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>

解决方案

There you go

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;
    }
}

and whenever something is changed, just call requestUpdate();

这篇关于与SurfaceView更换视图中绘制比UI线程其他的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆