1

I want to create an AsyncTask to post a canvas to a SurfaceView after a render process. But i was wondering how i can access the variables i give to the AsyncTask? So before i want to start rendering i have to get the Canvas and give it to my Render class. But this is not working:

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
}

}

Is it possible to do what i want with a AsyncTask?

EDITED

MyAsyncTask now looks like this:

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!");
}

}

In my MainActivity i call this at the 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);

But my View does not update if i run my app?

binaryBigInt
  • 1,526
  • 2
  • 18
  • 44

1 Answers1

2

Your renderer variable in the doInBackground method is an array of Renderer objects. You are passing this array when you are calling your AsyncTask execute() method:

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

I don't know what is your renderer object, so you can pass instead my new Renderer() anything you need. Then in doInBackground you can get this object with next

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

And now just remove you onPreExecute method at all.

EDITED

One more - you MyAsyncTask should extend AsyncTask : First is type of object that you pass to the AsyncTask, second is passed to method onProgressUpdate while task is running, and the last - type that your task return to main thread.

Orest Savchak
  • 4,529
  • 1
  • 18
  • 27
  • Yup, binaryBigInt, you might want to see this question on Java varargs - http://stackoverflow.com/questions/13665930/use-of-ellipsis-in-java – Victor KP Dec 23 '14 at 23:47
  • Thanks a lot for your answer. So it is not possible to access the SurfaceHolder or DrawingView? – binaryBigInt Dec 23 '14 at 23:49
  • Why not? You can pass to AsyncTask anything you want. You can do it with the same method, as I wrote about render, just use AsyncTask, then pass with calling task all you need: new MyAsyncTask().execute(render, surfaceHolder, drawingView) and in you doInBackground method get objects from array and cast it to reference you need. Also you can do this with constructor, as for me it will be more comfortable. – Orest Savchak Dec 23 '14 at 23:51
  • Is it possible to do a continuous update of the SurfaceView inside that AsyncTask or do i have to create a new one every time? – binaryBigInt Dec 23 '14 at 23:54
  • Oh. I think it is bad solution to do this with AsyncTask. You create AsyncTask for some large actions to do them in background and get the result. If you want to do a continuous update - it will be better to use service or some working thread. – Orest Savchak Dec 23 '14 at 23:59
  • In this case you should create new AsynkTask for each updating as you said – Orest Savchak Dec 24 '14 at 00:00
  • i edited my initial post, i would really appreciate it if you could have a second look at my current version. Thank you very much for your explanations – binaryBigInt Dec 24 '14 at 00:09
  • Sorry, I didn't work with such things. But all this you are doing is UI features, why don't you run it on UI thread? Also as I know postInvalidate may not works nice, you can try to make some callback and run this with runOnUiThread method in your activity, but I don't think that problem is here. – Orest Savchak Dec 24 '14 at 00:28
  • 1
    If you look at the output of `adb shell ps -p -t` you'll notice that AsyncTask threads run at a lower priority. It's meant for short-lived background tasks that shouldn't fight for CPU with the UI. Doing your rendering in an AsyncTask thread may not be the right approach. – fadden Dec 24 '14 at 01:48