我正在为Android扩展SurfaceView实现一个简单的渲染视图类。我的主要活动类包括用于其他操作的无限循环。
然而,当主要活动处于无限循环时,应用程序显示黑屏。据我所知,主活动和表面视图类有自己独立的线程,因此即使主活动类繁忙,表面视图类也应该保持渲染。当我通过设置'运行'来防止无限循环时,该应用程序工作正常代码中的布尔变量false。
当我的主要活动处于无限循环时,表面视图类停止渲染的原因是什么?
我的主要活动和表面视图类如下:
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的渲染类:
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
}
}
}
}
答案 0 :(得分:0)
此
renderView = new RenderSurfaceView(this);
setContentView(renderView);
不会立即显示视图。相反,它必须首先进行布局遍历,这不会立即发生,而是与Activity
生命周期方法异步发生,并且它发生在主线程上。因此,在onCreate()
末尾运行无限循环会阻止视图层次结构的布局遍历,这意味着您的SurfaceView
将永远不会显示。
理论上,您可以尝试使用Handler
开始延迟无限循环,但也可以用于实验目的。总的来说,主线程上的无限循环是一个非常糟糕的主意,除了实验之外我无法看到你想要这样做的原因。
我对这个问题的自我回答Modifying views in AsyncTask doInBackground() does not (always) throw exception详细介绍了幕后发生的事情。问题与你在这里提出的问题没有直接关系,但我认为背景是相同的。