为什么我的 Surface View Class 在 Main Activity 繁忙时停止渲染?

Why Does My Surface View Class Stops Rendering When Main Activity is Busy?

我正在为 Android 扩展 SurfaceView 实现一个简单的渲染视图 class。我的主要 activity class 包含用于其他操作的无限 while 循环。

但是,当 main activity 处于无限循环时,应用程序显示黑屏。据我所知,main activity 和 surface view classes 有自己独立的线程,所以 surface view class 即使在 main activity [=32= 时也应该保持渲染] 忙。当我通过在代码中设置 'running' 布尔变量 false 来防止无限循环时,该应用程序工作正常。

当我的主 activity 处于无限循环时,表面视图 class 停止渲染的原因可能是什么?

我的主要activity和表面视图class如下:

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity{
    RenderSurfaceView renderView;

    public boolean running = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate ( savedInstanceState );
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        renderView = new RenderSurfaceView(this);
        setContentView(renderView);

        loop();
    }

    public void loop(){
        running = true;
        while(running){

        }
    }

    protected void onResume() {
        super.onResume();
        renderView.resume();
    } 

    protected void onPause() {
        super.onPause();
        renderView.pause();
    }
}

这是我的扩展 SurfaceView 的渲染 class:

import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class RenderSurfaceView extends SurfaceView implements Runnable{
    Thread renderThread = null;
    SurfaceHolder holder;
    volatile boolean running = false;

    Random r = new Random();

    public RenderSurfaceView(Context context) {
        super(context);
        holder = getHolder();

    }

    public void resume() {
        running = true;
        renderThread = new Thread(this);
        renderThread.start();
    }

    public void run() {
        while(running) {
            if(!holder.getSurface().isValid())
                continue;
            render();
        }
    }

    private void render(){
        Canvas canvas = holder.lockCanvas();

        canvas.drawRGB(r.nextInt(255), r.nextInt(255), r.nextInt(255));

        holder.unlockCanvasAndPost(canvas);
    }

    public void pause() {
        running = false;
        while(true) {
            try {
                renderThread.join();
            } catch (InterruptedException e) {
                // retry
            }
        }
    }

}

这个

renderView = new RenderSurfaceView(this);
setContentView(renderView);

不立即显示视图。相反,它必须首先进行布局遍历,这不会立即发生,而是与 Activity 生命周期方法异步发生,并且发生在主线程上。所以 运行 在 onCreate() 末尾的无限循环阻止了视图层次结构的布局遍历,这意味着你的 SurfaceView 将永远不会显示。

理论上,出于实验目的,您可以尝试使用 Handler 延迟启动无限循环。一般来说,主线程上的无限循环是一个非常糟糕的主意,除了实验之外,我看不出你想要这样做的原因。

我对这个问题的自我回答 更详细地说明了幕后发生的事情。这个问题与你在这里问的问题没有直接关系,但我相信背景是一样的。