【问题标题】:How to call another activity from drawing thread (SurfaceView)如何从绘图线程(SurfaceView)调用另一个活动
【发布时间】:2020-06-09 19:22:53
【问题描述】:

目标是这样的: 我启动应用程序,MainActivity 启动一个绘图线程。 该线程一直绘制,直到其中发生某些事件(在我的情况下,值 i>155) 然后这个线程停止绘图(但它不应该被删除,并且值不应该丢失)并开始另一个活动(通常的 xml - 文件活动) 当我需要时,我应该能够进入我的绘图线程并从我弯腰的地方继续与它通信

为了解决这个问题,我决定在里面使用一个 SurfaceView 线程和 Canvas(最好把它做成一个类,而不是写在 MainActivity 中,因为我要在那里插入很多代码)。我设法启动了一个线程并在我的屏幕上绘制了一些东西,但我无法更改活动。最好的尝试是在 MainActivity 中创建一个处理程序并从我的线程那里发送一条消息。 该线程工作正常,但它只是冻结并且在需要更改 Activity 时没有任何反应。在日志选项卡中我可以看到线程发送了一条消息,但 MainActivity 看不到和处理它。

我该怎么办?解决问题的正确时间是什么时候?请帮助初学者)。

MainActivity 代码:

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainActivity extends Activity {

    public  Handler  h  =new  Handler() {
        public void handleMessage(android.os.Message msg) {
            Log.i("","recieved");

            if(msg.what==1){
                Intent intent = new Intent(MainActivity.this,ScrollingActivity.class);
                MainActivity.this.startActivity(intent);
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new DrawView(this));

    }

    class DrawView extends SurfaceView implements SurfaceHolder.Callback {

        private DrawThread drawThread;

        public DrawView(Context context) {
            super(context);
            getHolder().addCallback(this);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                   int height) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            drawThread = new DrawThread(getHolder());
            drawThread.setRunning(true);
            drawThread.start();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            boolean retry = true;
            drawThread.setRunning(false);
            while (retry) {
                try {
                    drawThread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }
        }

    }

}

DrawThread 类代码:

import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceHolder;

class DrawThread extends Thread {
    Canvas canvas;
    int i=0;
    private boolean running = false;
    private SurfaceHolder surfaceHolder;

    public DrawThread(SurfaceHolder surfaceHolder) {
        this.surfaceHolder = surfaceHolder;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    @Override
    public void run() {
        Looper.prepare();
        while (running) {
            canvas = null;
            try {
                canvas = surfaceHolder.lockCanvas(null);
                draw();
            } finally {
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }
    public void draw(){

        canvas.drawColor(Color.rgb(i,i,i));
        i++;
        if(i>155){
            i=0;
            running=false;
            sender snd = new sender();
            snd.send(1);


        }
    }
    private class sender extends MainActivity{
        public void send(int i){
            Log.i("","sending");
            try {
                h.sendEmptyMessage(i);
                Log.i("","sent");
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }
}

【问题讨论】:

    标签: java android multithreading handler surfaceview


    【解决方案1】:

    答案很简单:我必须将所有内容替换到一个文件中(到 MainAcitivity 类中,如这里https://startandroid.ru/ru/uroki/vse-uroki-spiskom/311-urok-141-risovanie-dostup-k-canvas.html)并创建一个可运行的,它调用一个活动。然后每次打开 MainActivity 时,图形线程都会启动,当需要更改 Activity 时,它会使用 runOnUIThread(runnable); 调用可运行对象。它暂停 MainActivity 并开始一个新的活动(!!任何暂停的 MainActivity 都会破坏我们的图形线程,任何恢复都会再次启动它,据我所知)。关闭新活动后,您将返回 MainActivity,我们的线程再次启动。 如果您不想丢失图形线程的值,您可以在活动类中声明这些值,而不是在线程类中(因为线程将在关闭活动屏幕时被销毁。(我看不到任何其他出路)

    P. S. 如果有任何错误,请纠正我。但是代码应该可以正常工作。

    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    public class MainActivity extends Activity {
        int i=0;
        //boolean firstRun=true;
        Runnable call = new Runnable() {
            public void run() {
                Log.i("","recieved");
                Intent intent=new Intent(MainActivity.this,ScrollingActivity.class);
    
                 startActivity(intent);
            }
        };
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new DrawView(this));
        }
    
        class DrawView extends SurfaceView implements SurfaceHolder.Callback {
    
            private DrawThread drawThread;
    
            public DrawView(Context context) {
                super(context);
                getHolder().addCallback(this);
            }
    
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                       int height) {
    
            }
    
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Log.i("","created");
                    drawThread = new DrawThread(getHolder());
                    drawThread.setRunning(true);
                    drawThread.start();
            }
    
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.i("","destroyed");
                boolean retry = true;
                drawThread.setRunning(false);
                while (retry) {
                    try {
                        drawThread.join();
                        retry = false;
                    } catch (InterruptedException e) {
                    }
                }
            }
    
            class DrawThread extends Thread {
    
                private boolean drawing=true;
                private boolean running = false;
                private SurfaceHolder surfaceHolder;
    
                public DrawThread(SurfaceHolder surfaceHolder) {
                    this.surfaceHolder = surfaceHolder;
                }
    
                public void setRunning(boolean running) {
                    this.running = running;
                }
    
                @Override
                public void run() {
                    Canvas canvas;
                    while (running) {
                        Log.i("","running");
                        if (drawing) {
                            canvas = null;
                            try {
                                canvas = surfaceHolder.lockCanvas(null);
                                if (canvas == null)
                                    continue;
                                canvas.drawColor(Color.rgb(i, i, i));
                                i++;
                                if (i == 100) {
                                    drawing = false;
                                    runOnUiThread(call);
                                }
                                if(i>255){
                                    i=0;
                                }
                            } finally {
                                if (canvas != null) {
                                    surfaceHolder.unlockCanvasAndPost(canvas);
                                }
                            }
                        }
                    }
                }
            }
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      相关资源
      最近更新 更多