2013-07-04 2 views
1

Я пытаюсь рисовать фрактал на SurfaceView внутри asynctask, но я не уверен, как правильно его выполнять. Моя идея состояла в том, чтобы создать surfaceview (в основном действии), который будет содержать индикатор выполнения, в то время как отдельный поток будет вычислять, какие пиксели будут рисоваться, и хранить их на каком-то «буфере» (я использую для этого холст). После этого на поверхности должен быть нарисован результат (который должен уничтожить вращающееся колесо индикатора прогресса).Android: Threaded drawing with asynctask

Я написал этот код:

MainActivity.java

public class MainActivity extends Activity { 
private Complex constant; 
private int bg_color, fg_color; 
private static final int nMax = 30, rMax = 2; 

private class JuliaThread extends AsyncTask<Complex, Void, Canvas> { 
    private double re, im, w, h; 
    private Complex sequence; 
    private int i; 
    private Canvas canv; 
    private Paint p; 
    private View m; 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     m = (View) findViewById(R.id.sv); 
     w = m.getWidth(); 
     h = m.getHeight(); 
     canv = new Canvas(); 
     p = new Paint(); 
    } 
    @Override 
    protected Canvas doInBackground(Complex... c) { 
     for (double y=0; y<h; y++) { 
      for (double x=0; x<w; x++) { 
       re = (x/w)*3.0-1.5; 
       im = -(y/h)*3.0-1.5; 
       sequence = new Complex(re, im); 
       for (i=1; i<=nMax; i++) { 
        sequence = sequence.square(); 
        sequence.add(c[0]); 
        if (sequence.abs() > rMax) break; 
       } 
       if (i == nMax) p.setColor(fg_color); 
       else p.setColor(bg_color); 
       canv.drawLine((float)x, (float)y, (float)x, (float)y, p); 
      } 
     } 
     return canv; 
    } 
    @Override 
    protected void onPostExecute(Canvas result) { 
     super.onPostExecute(result); 
     m.draw(result); 
    } 
} 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    constant = new Complex(-0.391, -0.587); 
    bg_color = Color.rgb(0, 0, 0); 
    fg_color = Color.rgb(255, 255, 255); 
    new JuliaThread().execute(constant); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 
} 

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".MainActivity" 
    android:id="@+id/mainview" > 

    <SurfaceView 
     android:id="@+id/sv" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentTop="true" > 

    </SurfaceView> 

    <ProgressBar 
     android:id="@+id/progressBar1" 
     style="?android:attr/progressBarStyleLarge" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignTop="@+id/sv" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="138dp" /> 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/progressBar1" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="15dp" 
     android:text="@string/loading" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 
</RelativeLayout> 

К сожалению, этот подход не работает. Не могли бы вы объяснить мне, что я делаю неправильно и как это сделать правильно?

ответ

0

Сначала необходимо получить SurfaceHolder от SurfaceView (путем внедрения SurfaceHolder.Callback). Затем сделайте что-нибудь вроде:

final Canvas c = mSurfaceHolder.lockCanvas(); 

//---draw stuff-- 

mSurfaceHolder.unlockCanvasAndPost(c); 
+0

Я не уверен, как это сделать с помощью асинтезы ...? Я создал класс, расширяющий SurfaceView, реализуя SurfaceHolder.Callback, но я не знаю, как получить этот «mSurfaceHolder», – TeoTN