2011-12-07 23 views
11

benim renderer başka bir sınıftan bazı değerlerin geçmek istiyorum. Oluşturucu değerlerini hesaplayıp sonra, oluşturucu yani bu yeni değerlerle devam edebilir hesaplama bittikten söyle gereken bir yardımcı sınıfında muteksi var. İşleyiciyi değerlerini sorunsuz bir şekilde iletebilirim, ancak bunları nasıl geri alacağımı anlayamıyorum. Şu anda bazı statik değişkenler kullanıyorum, ancak işleyici tarafından değiştirildikten sonra kayboluyor gibi görünüyorlar. Diğer sınıfımda görünmüyorlar. Örnek:Geçiş değişkenleri()

benim oluşturucunuz A sınıfı

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 
    } 
} 

My yardımcı sınıfı:

public class Helper{ 

public static volatile boolean hasCalculated = false; 

} 

hasCalculated kesinlikle Oluşturucu true olarak ayarlanmış, ancak benim diğer sınıf her zaman olduğu gibi yanlış görür. Bir fikrin neden? En iyi tahminim, çünkü onun başka bir iş parçacığında olması, fakat bunu nasıl çözebilirim? Daha temiz ve daha güvenli bir yaklaşım varsa, onu duymaktan memnuniyet duyarım.

cevap

14

İşleyicinizi aktivitenizde bir değişken olarak tutabilirsiniz (sadece mGLView.setRenderer(new MyRenderer()); yapmayın, bunun yerine pek çok kişi MyRenderer myRenderer = new MyRenderer(); mGLView.setRenderer(myRenderer);). Daha sonra, yöntem çağrıları yoluyla oluşturucunuzla kolayca iletişim kurabilirsiniz. Sorun daha sonra sadece çapraz-ileti iletişimine geliyor. Aşağıda iki örnek olmayan bir UI iş parçacığı, GL iplik ve ana UI iş parçacığı arasındaki iletişimi tane koyduk. İkinci örnek Oluşturucu

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 
    } 


} 


} 

Sonra sadece GL iplik ve UI iş parçacığı arasındaki iletişim için yukarıdaki oluşturucusu örnekte bayrakları kullandım

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 

    } 



} 

, ancak çevirmek oldukça basit olurdu diyelim ki, sen oluşturucusunu anlatmak istedim eğer bir kuyruğuna, "modellerin bu diziyi yükleyin". Eğer GL kolu kullanarak GL thread (veya en dokular az) modelleri yüklemek zorunda olduğundan, diğer sınıflar ve ipler mantık yapmak ve sadece GL şeyler GL iplik



yapmış olabilir Alternatif olarak, sadece senin hesaplama yapıldıktan sonra UI iplik güncelleme yerine başka iş parçacığı ile etkileşim istiyorsanız: yerden sonra

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 

    } 

} 

ve:

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 

     } 

    } 

}); 
+0

Vay, teşekkürler. İşe döndüğümde yarın daha yakından bakacağım. – Lennart