Android How to run AsyncTask every second?

I am new to Android and do not know how to solve this problem: I have AsyncTask that reads position (X, Y, Z) from an XML file. Since this position changes every second, I want, after I press the button (called "StartListener"), to read and draw each new position CONTINUOUSly and stop reading it when I press the button again ...
Can anybody help me? - This is part of my MainActivity

(At the moment, my application reads and draws a position only when I click 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 
+6
source share
2 answers

I think you complete too many tasks in just one second. Instead, you can prepare all the heavy staff in onPreExecute() , read the XML and make a picture in doInBackground() , resfresh ImageView in onProgressUpdate() and finally, when the task is completed, save the image in sdcard .

I modified your Asynctask to execute the above scenario, I have not tested it, but it gives you this idea.

In the onCreate() method of your activity, you run AsyncTask only once. It remains executing or sleeping until you set the Quit_Task variable to true. When the button is pressed, you switch the Do_Drawing: Do_Drawing=!Do_Drawing; variable Do_Drawing: Do_Drawing=!Do_Drawing; and her.

 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 
+1
source

you can use Handlers to handle this:

 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 the isBusy value to true when the async task is in doInBackground and returns false in the last line of onPostExecute.

when you press the stop button, set Stop to true, when the start button of the stop button is set to false

+1
source

Source: https://habr.com/ru/post/953499/


All Articles