Android Как запустить AsyncTask каждую секунду?

Я новичок в Android и не знаю,как справиться с этой проблемой: у меня есть AsyncTask,который читает позицию (X, Y, Z) из XML-файла. Поскольку эта позиция меняется каждую секунду, я хочу после нажатия кнопки (называемой "StartListener") читать и рисовать каждую новую позицию непрерывно и перестать читать ее, когда я снова нажимаю кнопку...
Кто-нибудь может мне помочь? - Вот часть моей основной деятельности

(на данный момент мое приложение читает и рисует только тогда, когда я нажать кнопку...)

      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

2 ответов


Я думаю, что вы делаете слишком много задач всего за одну секунду. Вместо этого вы могли бы подготовить весь тяжелый персонал в onPreExecute() AsyncTask, прочитайте XML и сделайте картину в doInBackground(), resfresh ImageView в onProgressUpdate() и, наконец, когда задача будет выполнена, сохраните изображение в sdcard.

Я изменил ваш Asynctask чтобы выполнить вышеуказанный сценарий, я не тестировал его, но он дает вам идею.

на onCreate() метод вашей деятельности, вы начинаете AsyncTask только один раз. Он остается выполняемым или спящим, пока вы не установите переменную Quit_Task в true. При нажатии кнопки вы переключаете переменную Do_Drawing: Do_Drawing=!Do_Drawing; и это все.

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

вы можете использовать обработчики, чтобы справиться с этим:

private boolean isBusy = false;//this flag to indicate whether your async task completed or not
private boolean stop = false;//this flag to indicate whether your button stop clicked
private Handler handler = new Handler();

public void startHandler()
{
    handler.postDelayed(new Runnable()
    {

        @Override
        public void run()
        {
            if(!isBusy) callAysncTask();

            if(!stop) startHandler();
        }
    }, 1000);
}

private void callAysncTask()
{
    //TODO
    new PositionAsync().execute();
}

set isBusy true, когда асинхронная задача в doInBackground и установите ее обратно в false в последней строке onPostExecute.

при нажатии кнопки стоп set остановка в true, когда нажмите кнопку Пуск set остановка в false