0

Im struggling a little bit with Asynctask and I would need some help.

I am plotting some graphs with Androidplot and, as it is extremely slow, I want to use Asynctask to do it faster.

The problem is that I don´t know how to access to the elements that I have declared in onCreate() from the Asynctask class. Here is the code:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.waveform);

     plot = (XYPlot) findViewById(R.id.XYPlot0);
        widget = plot.getGraphWidget();
        plot2= (XYPlot) findViewById(R.id.XYPlot01);
        widget2=plot2.getGraphWidget();
        plot3= (XYPlot) findViewById(R.id.XYPlot02);
        widget3=plot3.getGraphWidget();


        Operaciones2 ope=new Operaciones2();
        ope.execute();

     // Turn the above arrays into XYSeries':
        XYSeries series1 = new SimpleXYSeries(
                Arrays.asList(n),          // SimpleXYSeries takes a List so turn our array into a List
                SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
                "Series1");   

        XYSeries series2 = new SimpleXYSeries(
                Arrays.asList(l),          // SimpleXYSeries takes a List so turn our array into a List
                SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
                "Series1"); 

         XYSeries series3 = new SimpleXYSeries(
                Arrays.asList(g2),          // SimpleXYSeries takes a List so turn our array into a List
                SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
                "Series1");



        // Create a formatter to use for drawing a series using LineAndPointRenderer
        // and configure it from xml:
        LineAndPointFormatter series1Format = new LineAndPointFormatter();
        //series1Format.setLinePaint(paint);
        series1Format.setPointLabelFormatter( (PointLabelFormatter) null); // con esto en null borramos el valor de las muestras de encima de los puntitos
        series1Format.getVertexPaint().setStrokeWidth(1); //Establece el tamaño de los puntos de cada muestra
        Paint linePaint=new Paint();
        Paint verPaint=new Paint();
        switch(color){
        case Color.BLUE: 
            //linePaint.setColor(Color.BLUE);
            //verPaint.setColor(this.getResources().getColor(R.color.DarkBlue));
            series1Format.configure(getApplicationContext(),R.xml.line_blue);
        break;
        case Color.RED:
            //linePaint.setColor(Color.RED);
            //verPaint.setColor(this.getResources().getColor(R.color.DarkRed));
            series1Format.configure(getApplicationContext(),R.xml.line_red);
        break;
        case Color.GREEN:
            //linePaint.setColor(Color.GREEN);
            //verPaint.setColor(this.getResources().getColor(R.color.DarkGreen));
            series1Format.configure(getApplicationContext(),R.xml.line_point_formatter_with_plf1);
        break;
        }
        int i;

Then I have the Asynctask code here:

  private class Operaciones2 extends AsyncTask<Void, Integer, Void> {
    int progress;   
    double [] st =new double [arr.length];
    int j=0;


    protected void onPostExecute(Void... unused ){
        plot.addSeries(series1, series1Format);
        plot2.addSeries(series2, series1Format);
        plot3.addSeries(series3, series1Format);
        Toast.makeText(getApplicationContext(), "Todo cargado", Toast.LENGTH_LONG).show();
    }

    protected Void doInBackground(Void... unused){


            for (int i = 44; i < s; i+=2) {
                // convert byte pair to int
                double audioSample = (double) (array[i+1] << 8 | array[i] & 0xff)/ 32767.0;

                arr[j]=audioSample;  //double
                n[j] = (Number)arr[j];  //Number

                st[j]=10*Math.log10(Math.abs((audioSample/Math.pow(10, -12)))); //double
                l[j]=(Number)(10*Math.log10(Math.abs((audioSample/Math.pow(10, -12)))));  //Number

                if(audioSample == 0.0 ){
                    if(j!=0){
                    l[j]=l[j-1];
                    st[j]=st[j-1];
                    }else{
                        l[j]=0.0;
                        st[j]=0.0;
                    }
                  }

                j=j+1;}
                min=Operaciones.minimum(arr);
                max=Operaciones.maximum(arr);
                min2=Operaciones.minimum(st);
                max2=Operaciones.maximum(st);
                /*****************************/
                arreaFFT();
            return null;
    }
 }

My idea is to add the series calculated at doInBackground into onPostExecute, but the problem is that I don´t really know how to access to series1-2-3 and series1Format created in onCreate() from the AsyncTask (it says that they cannot be resolved to a variable).

Any ideas??

paviflo
  • 105
  • 2
  • 13
  • Just a quick note: as written above, only your FFT code is done in the background, which might be reasonable for your implementation. But, if you are still encountering slowness at the render stage ('slow' meaning enough delay to cause the main thread to appear to be unresponsive either to the user, OS or both) then you might want to use Androidplot's background rendering mode. – Nick Jun 08 '14 at 15:29
  • Hi Nick, thank you for your answer. As you say, it is not going yet as fast as I would like to, I´ve been trying to investigate about the background rendering mode, but I did not find a clear explanation of how does this actually work and how to implement it. Do you know where can I find more info? btw: great work with AndroidPlot – paviflo Jun 08 '14 at 16:13
  • The best resource is probably the [source code of the DemoApp's Orientation Sensor Example](https://bitbucket.org/androidplot/androidplot/src/d90fc9fe7705a3f82fe44406cd28a34d9169e056/Examples/DemoApp/src/com/androidplot/demos/OrientationSensorExampleActivity.java?at=master). Given your code above I'm assuming your plot is not dynamic - can you confirm that? Also how many points are in each series? – Nick Jun 08 '14 at 17:50
  • Yes, my plot is not dynamic. The number of points depends on the sample rate selected by the user, so it may range from 8000 to 45000 points aproximately – paviflo Jun 08 '14 at 19:37
  • In that case the benefit background rendering will offer you is the ability to show an animated progress dialog while rendering. definitely a step up from a frozen screen but technically not faster. 45,000 points is a lot and is going to take a while no matter what. I usually suggest using some form of interpolation to get that number < 1000. [Here's a link to a similar topic](https://groups.google.com/forum/?fromgroups#!searchin/androidplot/interpolation/androidplot/6Vte1F6Sid4/50NPQ1yFRFMJ) – Nick Jun 09 '14 at 13:04

3 Answers3

1

Just provide a callback in the AsyncTask constructor. This is generally the Activity (or Fragment) itself, implementing a particular interface.

See Android, can I put AsyncTask in a separate class and have a callback?

This is a common pattern with AsyncTask.

Community
  • 1
  • 1
matiash
  • 54,791
  • 16
  • 125
  • 154
0

You can make UI changes only in onProgressUpdate and onPostexecute methods of AsyncTask.

Volodymyr Kulyk
  • 6,455
  • 3
  • 36
  • 63
0

Other option would be declaring your series1Format and plot as a member of the class, then you could access it from onPostExecute

public myActivity extends Activity{
    LineAndPointFormatter mSeries1Format;
    // Declare plot as member


    protected void onCreate(Bundle savedInstanceState) {
        // Initialize mSeries1Format
    }      

}
Alejandro Alcalde
  • 5,990
  • 6
  • 39
  • 79
  • 06-07 20:49:43.237: E/AndroidRuntime(14829): Caused by: java.lang.NullPointerException at android.util.TypedValue.applyDimension(TypedValue.java:333) at com.androidplot.util.PixelUtils.dpToPix(PixelUtils.java:103) at com.androidplot.xy.LineAndPointFormatter.initLinePaint(LineAndPointFormatter.java:101) at com.androidplot.xy.LineAndPointFormatter.(LineAndPointFormatter.java:63) at com.androidplot.xy.LineAndPointFormatter.(LineAndPointFormatter.java:74) at com.androidplot.xy.LineAndPointFormatter.(LineAndPointFormatter.java:70) at com.example.acoustics.Grafica. – paviflo Jun 07 '14 at 18:53
  • Have you initialized `series1Format = new LineAndPointFormatter();` in `onCreate`? – Alejandro Alcalde Jun 07 '14 at 18:55
  • yes, the rest remains exactly the same, I just moved the line series1Format = new LineAndPointFormatter(); out of onCreate(), the other ones are in the same place – paviflo Jun 07 '14 at 19:03
  • No, you need to have it inside of `onCreate` difference is that now it is a member of the class. – Alejandro Alcalde Jun 07 '14 at 19:05
  • 1
    ok, now I got it, stupid mistake, im still quite new with this, thanks! – paviflo Jun 07 '14 at 19:11