使用queueEvent()在渲染器和另一个类之间传递变量

我想将其他类的一些值传递给渲染器。渲染器计算出值之后,我在帮助器类中有了一个互斥锁,该互斥体应该告诉我渲染器已完成计算,因此我可以继续使用这些新值。我可以毫无问题地传递渲染器的值,但是我不知道如何找回它们。我目前使用一些静态变量,但是在渲染器更改它们之后,它们似乎丢失了。它们在我的其他课程中不可见。例:

public class View extends SurfaceView{

private void doSomething(){

glSurfaceView.queueEvent(new Runnable() {

@Override

public void run() {

//..

renderer.calculate(stack);

}

});

}

private void doAnotherThing(){

//Never happens:

if(Helper.hasCalculated){

/...

}

}

}

public class MyRenderer implements GLSurfaceView.Renderer{

private void calculate(Stack stack){

Helper.hasCalculated = true

}

}

public class Helper{

public static volatile boolean hasCalculated = false;

}

hasCalculated在渲染器中肯定设置为true,但是我的其他类始终将其视为false。知道为什么吗?我最好的猜测是这是因为它在另一个线程中,但是我该如何解决呢?如果有更清洁,更安全的方法,我很高兴听到他的声音。

回答:

您可以在活动中将渲染器作为变量保存(不像mGLView.setRenderer(new

MyRenderer());很多人那样,而是MyRenderer myRenderer = new MyRenderer();

mGLView.setRenderer(myRenderer);)。然后,您可以通过方法调用轻松地与渲染器进行通信。然后问题就归结为跨线程通信。我在下面放置了两个示例,一个示例用于非UI线程,GL线程和主UI线程之间的通信。第二个示例仅用于GL线程和UI线程之间的通信

public class Test3D extends Activity{

private MyRenderer renderer; // keep hold of the renderer as a variable in activity

private MyAsyncTask gameLoop;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

myRenderer = new MyRenderer(); // create the renderer object

GLSurfaceView mGLView = (GLSurfaceView)findViewById(R.id.glsurfaceview1);

mGLView.setEGLConfigChooser(true);

mGLView.setRenderer(myRenderer); // set the surfaceView to use the renderer

gameLoop = new MyAsyncTask();

gameLoop.execute(); // start a new, non-UI, thread to do something

}

/// non-UI thread (inner class of my Test3D activity)

class MyAsyncTask extends AsyncTask<Void, Void, Void>{

@Override

protected Void doInBackground(Void... arg0) {

myRenderer.startCalc(); // tell renderer to start calculation

while(!myRenderer.isFinishedCalc()){

// waiting for calc to finish, but not blocking UI thread

try {

long x = 1000;

Thread.sleep(x);

// sleep the thread for x amount of time to save cpu cycles

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

publishProgress(null);

// when calculation has finished, we will drop out of the loop

// and update the UI

}

protected void onProgressUpdate(Void... progress) {

// update UI

}

}

}

然后在渲染器中

public class MyRenderer implements Renderer{

private boolean startCalc = false;

private boolean finishCalc = false;

public void startCalc(){

finishCalc = false;

startCalc = true;

}

public boolean isFinishedCalc(){

return finishCalc;

}

public void onDraw(GL10 gl){

if(startCalc){

// do calculation using GL handle

// always performed in the GL thread

finishCalc = true;

startCalc = false;

}

// draw

}

}

我在上面的渲染器示例中使用了标志,但是,例如,如果您要告诉渲染器“加载此模型数组”,将其转换为队列将非常简单。由于您必须使用GL句柄将模型(或至少纹理)加载到GL线程中,因此可以让其他类和线程来执行逻辑,而仅在GL线程中完成GL的工作


另外,如果您只想在完成计算后更新UI线程,而不是与任何其他线程进行交互:

public class MyRenderer implements Renderer{

private Handler handler = null;

public static final int CALC_FINISHED = 1;

public void startCalc(Handler handler){

this.handler = handler;

}

public void onDraw(GL10 gl){

if(handler!=null){

// do calculation using GL handle

int flag = MyRenderer.CALC_FINISHED;

handler.dispatchMessage(Message.obtain(handler, flag));

// adds a message to the UI thread's message queue

handler = null;

}

// draw

}

}

然后从任何地方:

myRenderer.startCalc(new Handler(){

public void handleMessage (Message msg){

if(msg.what==MyRenderer.CALC_FINISHED){

// Update UI

// this code will always be executed in the UI thread

}

}

});

以上是 使用queueEvent()在渲染器和另一个类之间传递变量 的全部内容, 来源链接: utcz.com/qa/404724.html

回到顶部