Bạn có thể giữ trình kết xuất của mình dưới dạng biến trong hoạt động của mình (không chỉ làm mGLView.setRenderer(new MyRenderer());
như nhiều người làm, mà là MyRenderer myRenderer = new MyRenderer(); mGLView.setRenderer(myRenderer);
). Sau đó, bạn có thể giao tiếp với trình kết xuất của mình dễ dàng thông qua các cuộc gọi phương thức. Vấn đề sau đó chỉ đi xuống để giao tiếp qua chủ đề. Tôi đã đưa hai ví dụ dưới đây, một ví dụ với giao tiếp giữa một chủ đề không phải UI, chủ đề GL và luồng giao diện người dùng chính. Ví dụ thứ hai là chỉ để liên lạc giữa các chủ đề GL và thread 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
}
}
}
Sau đó, trong renderer
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
}
}
Tôi đã sử dụng lá cờ trong ví dụ renderer trên, nhưng nó sẽ là khá đơn giản để biến mà vào một hàng đợi, nếu, nói, bạn muốn nói với trình kết xuất "nạp mảng mô hình này". Vì bạn phải tải các mô hình (hoặc ít nhất là kết cấu) trong thread GL sử dụng tay cầm GL, bạn có thể có các lớp học và chủ đề khác làm logic của bạn và vừa những thứ GL thực hiện trong thread GL
Ngoài ra, nếu bạn chỉ muốn cập nhật các thread UI sau khi tính toán của bạn được thực hiện, chứ không phải tương tác với bất kỳ chủ đề khác:
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
}
}
và sau đó từ bất cứ nơi nào:
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
}
}
});
Wow, cảm ơn. Tôi sẽ có một cái nhìn gần hơn vào ngày mai khi tôi trở lại làm việc. – Lennart