Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用queueEvent()在呈现程序和另一个类之间传递变量_Java_Android_Multithreading_Opengl Es - Fatal编程技术网

Java 使用queueEvent()在呈现程序和另一个类之间传递变量

Java 使用queueEvent()在呈现程序和另一个类之间传递变量,java,android,multithreading,opengl-es,Java,Android,Multithreading,Opengl Es,我想向渲染器传递另一个类的一些值。在渲染器计算完这些值之后,我在助手类中有一个互斥对象,它应该告诉我渲染器已经完成了计算,所以我可以继续使用这些新值。我可以毫无问题地将值传递给渲染器,但我不知道如何将它们返回。我目前使用一些静态变量,但在渲染器更改它们之后,它们似乎丢失了。它们在我的另一个类中不可见。 例如: 一门课 public class View extends SurfaceView{ private void doSomething(){ glSurfaceView.

我想向渲染器传递另一个类的一些值。在渲染器计算完这些值之后,我在助手类中有一个互斥对象,它应该告诉我渲染器已经完成了计算,所以我可以继续使用这些新值。我可以毫无问题地将值传递给渲染器,但我不知道如何将它们返回。我目前使用一些静态变量,但在渲染器更改它们之后,它们似乎丢失了。它们在我的另一个类中不可见。 例如:

一门课

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
    }


}


}
我在上面的渲染器示例中使用了标志,但是如果您想告诉渲染器“加载此模型数组”,那么将其转换为队列将非常简单。由于您必须使用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

        }

    }

});

哇,谢谢。我明天回去工作时会仔细看一看。
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

        }

    }

});