Search code examples
androidandroid-asynctaskcontinuous

Android How to run an AsyncTask every second?


I'm new in Android and not really knowing how to deal this problem: I have an AsyncTask which reads a position (X,Y,Z) from a XML file. As this position changes every second, I want, after I push a button (called with "StartListener") to read and draw every new position CONTINUOUSLY and stop reading it when I press the button again...
Somebody can help me? - Here is a part of my MainActivity

(For the moment my app reads and draws a position only when I press the button...)

      private OnClickListener StartListener = new OnClickListener() {

          @Override
          public void onClick(View v) {

                TextView ButText = (TextView)findViewById(R.id.buttonStart);

                 String value=ButText.getText().toString();
                 if(value.equals("Start positioning")){
                     ButText.setText("Stop positioning");

                     new PositionAsync().execute(); //read data from XML file

                 }
                 else if(value.equals("Stop positioning")){
                     ButText.setText("Start positioning");
                     //new PositionAsync().cancel(true);
                 }              
            }                   
      }; // END LISTENER START BUTTON


// READ XML FILE
class PositionAsync extends AsyncTask<Void, Void, Void> {

    XMLHelper helper;
    @Override
    protected Void doInBackground(Void... arg0) {
        helper = new XMLHelper();
        helper.get();
        return null;
    }   

    @Override
    protected void onPostExecute(Void result) {         

        Paint paintBlack = new Paint(); paintBlack.setAntiAlias(true); paintBlack.setColor(Color.BLACK);

        BitmapFactory.Options myOptions = new BitmapFactory.Options();
        myOptions.inDither = true;
        myOptions.inScaled = false;
        myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
        myOptions.inPurgeable = true;
        File ImageSource = new File("/sdcard/app_background3.jpg");
        Bitmap bitmap2 = BitmapFactory.decodeFile(ImageSource.getAbsolutePath(),myOptions);         
        Bitmap workingBitmap = Bitmap.createBitmap(bitmap2);
        Bitmap mutableBitmap2 = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);

        Canvas canvas2 = new Canvas(mutableBitmap2);

        float RoomWidthPx = canvas2.getWidth();
        float RoomHeightPx = canvas2.getHeight();
        float RoomXmeter = (float) 9.3;
        float RoomZmeter = (float) 14.7;

        for (PositionValue position : helper.positions) {

            String PosX = position.getPositionX(); String PosY = position.getPositionY(); String PosZ = position.getPositionZ();

            float x = Float.valueOf(PosX); float y = Float.valueOf(PosY); float z = Float.valueOf(PosZ);

            float xm = x*RoomWidthPx/RoomXmeter; 
            float zm = z*RoomHeightPx/RoomZmeter;

            canvas2.drawCircle(xm, zm, 25, paintBlack);

            ImageView imageView = (ImageView)findViewById(R.id.imageView1);
            imageView.setAdjustViewBounds(true);
            imageView.setImageBitmap(mutableBitmap2);

            // SAVE DRAWINGS INTO FILE
            FileOutputStream fos = null;
            try {
            fos = new FileOutputStream ("/sdcard/app_background3.jpg");
            mutableBitmap2.compress (Bitmap.CompressFormat.JPEG, 95, fos); 
            } catch (Throwable ex) {ex.printStackTrace (); }    
        };

    }
} //END READ XML FILE

Solution

  • I think you are doing too many task in just one second. You could, instead, prepare all heavy staff in the onPreExecute() of the AsyncTask, read the XML and do the painting in the doInBackground(), resfresh the ImageView in the onProgressUpdate() and finally, when the task is done, save the image to the sdcard.

    I've modified your Asynctask to accomplish the above scenario, I've not tested it but it gives you the idea.

    In the onCreate() method of your activity you start the AsyncTask just once. It stays executing or sleeping until you set the Quit_Task variable to true. When the button is pressed you toggle the variable Do_Drawing: Do_Drawing=!Do_Drawing; and that's it.

    private boolean Do_Drawing = false;
    private boolean Quit_Task = false;
    
    // READ XML FILE
    class PositionAsync extends AsyncTask<Void, Void, Void>
    {
        Paint paintBlack;
        BitmapFactory.Options myOptions;
        Bitmap mutableBitmap2;
        Canvas canvas2;
        XMLHelper helper;
    
        void Sleep(int ms)
        {
            try
            {
                Thread.sleep(ms);
            }
            catch (Exception e)
            {
            }
        }
    
        @Override
        protected void onPreExecute()
        {
            // Prepare everything for doInBackground thread
            paintBlack = new Paint();
            paintBlack.setAntiAlias(true);
            paintBlack.setColor(Color.BLACK);
            myOptions = new BitmapFactory.Options();
            myOptions.inDither = true;
            myOptions.inScaled = false;
            myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
            myOptions.inPurgeable = true;
            File ImageSource = new File("/sdcard/app_background3.jpg");
            Bitmap bitmap2 = BitmapFactory.decodeFile(ImageSource.getAbsolutePath(), myOptions);
            Bitmap workingBitmap = Bitmap.createBitmap(bitmap2);
            mutableBitmap2 = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
            canvas2 = new Canvas(mutableBitmap2);
            helper = new XMLHelper();
        }
    
        @Override
        protected Void doInBackground(Void... arg0)
        {
            while (!Quit_Task)
            {
                // Sleep until button is pressed or quit
                while (!Do_Drawing)
                {
                    Sleep(1000);
                    if (Quit_Task)
                        return null;
                }
    
                float RoomWidthPx = canvas2.getWidth();
                float RoomHeightPx = canvas2.getHeight();
                float RoomXmeter = (float) 9.3;
                float RoomZmeter = (float) 14.7;
                // keep drawing until button is pressed again or quit
                while (Do_Drawing)
                {
                    if (Quit_Task)
                        return null;
                    helper.get();
                    for (PositionValue position : helper.positions)
                    {
                        String PosX = position.getPositionX();
                        String PosY = position.getPositionY();
                        String PosZ = position.getPositionZ();
    
                        float x = Float.valueOf(PosX);
                        float y = Float.valueOf(PosY);
                        float z = Float.valueOf(PosZ);
    
                        float xm = x * RoomWidthPx / RoomXmeter;
                        float zm = z * RoomHeightPx / RoomZmeter;
    
                        canvas2.drawCircle(xm, zm, 25, paintBlack);
                    }
                    this.publishProgress((Void) null);
                    Sleep(1000);
                }
            }
            return null;
        }
    
        @Override
        protected void onProgressUpdate(Void... progress)
        {
            // once all points are read & drawn refresh the imageview
            try
            {
                ImageView imageView = (ImageView) findViewById(R.id.imageView1);
                imageView.setAdjustViewBounds(true);
                imageView.setImageBitmap(mutableBitmap2);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    
        @Override
        protected void onPostExecute(Void result)
        {
            // SAVE DRAWINGS INTO FILE once the task is done.
            FileOutputStream fos = null;
            try
            {
                fos = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "app_background3.jpg");
                mutableBitmap2.compress(Bitmap.CompressFormat.JPEG, 95, fos);
            }
            catch (Throwable ex)
            {
                ex.printStackTrace();
            }
        }
    } // END READ XML FILE