2014-12-23 4 views
1

Я хочу создать AsyncTask для публикации холста SurfaceView после процесса рендеринга. Но мне было интересно, как я могу получить доступ к переменным, которые я предоставляю AsyncTask? Поэтому, прежде чем я хочу начать рендеринг, я должен получить Canvas и передать его в класс Render. Но это не работает:Вызов AsyncTask с различными параметрами

public class MyAsyncTask extends AsyncTask<DrawingView, SurfaceHolder, Renderer>{ 
private Canvas cv = null; 

@Override 
protected void onPreExecute(){ 
    this.cv = SurfaceHolder.lockCanvas(); //get canvas 
} 

@Override 
protected Canvas doInBackground(Renderer...render){ 
    render.canvas = this.cv; //give the canvas to the renderer 
    render.RenderOneStep(); //rendering 
    return render.DisplayResult(); //gives back a canvas 
} 

@Override 
protected void onPostExecute(Canvas canvas){ 
    this.SurfaceHolder.unlockCanvasAndPost(canvas); //post canvas back to surfaceHolder 
    this.DrawingView.postInvalidate(); //update SurfaceView 
} 

}

Можно ли делать то, что я хочу с AsyncTask?

EDITED

MyAsyncTask теперь выглядит следующим образом:

public class MyAsyncTask extends AsyncTask<Object,Void,Canvas>{ 

private DrawingView dView = null; 
private SurfaceHolder holder = null; 

@Override 
protected Canvas doInBackground(Object...obj){ 
    dView = (DrawingView)obj[0]; 
    holder = (SurfaceHolder)obj[1]; 
    Renderer renderer = (Renderer)obj[2]; 

    Canvas cv = holder.lockCanvas(); 
    renderer.canvas = cv; 
    renderer.RenderOneStep(); //rendering 
    return renderer.DisplayResult(); //returns a canvas 
} 

@Override 
protected void onPostExecute(Canvas canvas){ 
    holder.unlockCanvasAndPost(canvas); 
    dView.postInvalidate(); 
    Log.e("Info-->", "Done!"); 
} 

}

В моей MainActivity я называю это в surfaceCreated Event:

Canvas cv = holder.lockCanvas(); 
this.render = new Renderer(new Scene(), cv, new Vector3D(0.0f, 0.0f, 10.0f), 4); 
holder.unlockCanvasAndPost(cv); 
new MyAsyncTask().execute(dView, holder, render); 

Но мой просмотр не обновляется, если я запустил приложение?

ответ

2

Переменная renderer в методе doInBackground представляет собой массив объектов Renderer. Вы проходите этот массив, когда вы вызываете ваш AsyncTask выполнить() метод:

new MyAsyncTask().execute(new Renderer()); 

Я не знаю, что ваш объект визуализации, так что вы можете передать вместо моего нового Renderer() все, что вам нужно. Тогда в doInBackground вы можете получить этот объект со следующими

@Override 
protected Canvas doInBackground(Renderer...renders){ 
    Renderer render = renders[0]; 

    render.canvas = SurfaceHolder.lockCanvas(); //give the canvas to the renderer 
    render.RenderOneStep(); //rendering 
    return render.DisplayResult(); //gives back a canvas 
} 

А теперь просто удалить вас onPreExecute метод вообще.

EDITED

еще один - вы MyAsyncTask должны распространяться AsyncTask: Во-первых это тип объекта, который вы передаете AsyncTask, второй передается методу onProgressUpdate в то время как задача выполняется, а последний - тип, что ваш задача вернуться в основной поток.

+0

Yup, binaryBigInt, вы можете посмотреть этот вопрос на Java varargs - http://stackoverflow.com/questions/13665930/use-of-ellipsis-in-java –

+0

Большое спасибо за ваш ответ. Таким образом, невозможно получить доступ к SurfaceHolder или DrawingView? – binaryBigInt

+0

Почему бы и нет? Вы можете перейти к AsyncTask, что угодно. Вы можете сделать это с помощью того же метода, который я написал об рендере, просто используйте AsyncTask , а затем передайте с вызывающей задачей все, что вам нужно: new MyAsyncTask(). Execute (render, surfaceHolder, drawingView) и в вашем методе doInBackground получить объекты из массива и применить его к нужной ссылке. Также вы можете сделать это с помощью конструктора, так как для меня это будет более комфортно. –