Note that there are some explanatory texts on larger screens.

plurals
  1. POAsyncTask app still running slowly
    primarykey
    data
    text
    <p>I've an app that places an effect on a bitmap. When the user slides the slidebar the level of distortion of the efect increases/decreases and the bitmap is then redrawn. My custom view class is called TouchView and this class gets the bitmap and calls a method from the Filters class that processes the image. I've had help implementing asyncTask to speed the processing up but to no avail. Is AsyncTask implemented properly. Thanks Matt.</p> <pre><code>public class TouchView extends View{ private File tempFile; private byte[] imageArray; private Bitmap bgr; private Bitmap bm; private Bitmap bgr2 = null;; private Paint pTouch; private int centreX = 1; private int centreY = 1; private int radius = 50; private int Progress = 1; private static final String TAG = "*********TouchView"; private Filters f = null; private boolean AsyncRunning = false; public TouchView(Context context) { super(context); // TouchView(context, null); } public TouchView(Context context, AttributeSet attr) { super(context,attr); //.....code that gets the bitmap from camera and sdcard bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo); bgr = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); bgr = bm.copy(bm.getConfig(), true); bgr2 = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); // instantiate the image processing class f = new Filters(); }// end of touchView constructor public void findCirclePixels(){ //set level of distortion float prog = (float)Progress/150000; // call processing method on bitmap bgr2 = f.barrel(bgr,prog); }// end of changePixel() }//end of onTouchEvent public void initSlider(final HorizontalSlider slider) { Log.e(TAG, "******setting up slider*********** "); slider.setOnProgressChangeListener(changeListener); } private OnProgressChangeListener changeListener = new OnProgressChangeListener() { @Override public void onProgressChanged(View v, int progress) { // TODO Auto-generated method stub setProgress(progress); Log.e(TAG, "***********progress = "+Progress); } }; private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { protected void onPreExecute() { } @Override protected Void doInBackground(Void... params) { TouchView.this.findCirclePixels(); return null; } protected void onPostExecute(Void result) { TouchView.this.invalidate(); } } @Override public void onDraw(Canvas canvas){ super.onDraw(canvas); canvas.drawBitmap(bgr2, 0, 0, null); }//end of onDraw protected void setProgress(int progress2) { this.Progress = progress2; new MyTask().execute(); } } </code></pre> <p>.</p> <p><strong>[update]</strong> This is what i've got now. The app is running slower now unfortunately. Have you any further ideas that i could try?</p> <pre><code>public class TouchView extends View{ private File tempFile; private byte[] imageArray; private Bitmap bgr; private Bitmap bm; private Bitmap bgr2 = null;; private Paint pTouch; private int centreX = 1; private int centreY = 1; private int radius = 50; private int Progress = 1; private static final String TAG = "*********TouchView"; private Filters f = null; private boolean AsyncRunning = false; private MyTask mt = null; public TouchView(Context context) { super(context); // TouchView(context, null); } public TouchView(Context context, AttributeSet attr) { super(context,attr); tempFile = new File(Environment.getExternalStorageDirectory(). getAbsolutePath() + "/"+"image.jpg"); imageArray = new byte[(int)tempFile.length()]; try{ InputStream is = new FileInputStream(tempFile); BufferedInputStream bis = new BufferedInputStream(is); DataInputStream dis = new DataInputStream(bis); int i = 0; while (dis.available() &gt; 0) { imageArray[i] = dis.readByte(); i++; } dis.close(); } catch (Exception e) { e.printStackTrace(); } BitmapFactory.Options bfo = new BitmapFactory.Options(); bfo.inSampleSize = 1; bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo); bgr = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); bgr = bm.copy(bm.getConfig(), true); bgr2 = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); f = new Filters(); }// end of touchView constructor public void findCirclePixels(){ float prog = (float)Progress/150000; bgr2 = f.barrel(bgr,prog); }// end of changePixel() public void initSlider(final HorizontalSlider slider) { Log.e(TAG, "******setting up slider*********** "); slider.setOnProgressChangeListener(changeListener); } private OnProgressChangeListener changeListener = new OnProgressChangeListener() { @Override public void onProgressChanged(View v, int progress) { // TODO Auto-generated method stub setProgress(progress); Log.e(TAG, "***********progress = "+Progress); } }; private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { protected void onPreExecute() { } @Override protected Void doInBackground(Void... params) { TouchView.this.findCirclePixels(); return null; } protected void onPostExecute(Void result) { while(!isCancelled()){ TouchView.this.invalidate(); } mt.cancel(true); } } @Override public void onDraw(Canvas canvas){ super.onDraw(canvas); canvas.drawBitmap(bgr2, 0, 0, null); canvas.drawCircle(centreX, centreY, radius,pTouch); }//end of onDraw protected void setProgress(int progress2) { this.Progress = progress2; mt = new MyTask(); mt.execute(); AsyncRunning = true; } } </code></pre> <p>.</p> <p>[update 2]</p> <pre><code>import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.ProgressBar; public class HorizontalSlider extends ProgressBar { private OnProgressChangeListener listener; private static int padding = 2; public interface OnProgressChangeListener { void onProgressChanged(View v, int progress); } /* public HorizontalSlider(Context context, AttributeSet attrs, Map inflateParams, int defStyle) { super(context, attrs, inflateParams, defStyle); } public HorizontalSlider(Context context, AttributeSet attrs, Map inflateParams) { super(context, attrs, inflateParams, android.R.attr.progressBarStyleHorizontal); }*/ public HorizontalSlider(Context context) { super(context); } public HorizontalSlider(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public void setOnProgressChangeListener(OnProgressChangeListener l) { listener = l; } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { float x_mouse = event.getX() - padding; float width = getWidth() - 2*padding; int progress = Math.round((float) getMax() * (x_mouse / width)); if (progress &lt; 0) progress = 0; this.setProgress(progress); if (listener != null) listener.onProgressChanged(this, progress); } return true; } } </code></pre> <p>.</p> <p><strong>[update 3]</strong></p> <p>Hi, ok i've changed my code to your amendements and changed i couple of lines so the view is updated by adding TouchView.this.invalidate() etc. Regarding the the horizontalSlider i've set it to check for only ACTION_UP when setting the progress. This way the user can move the slidebar but the view is only invalidated when the user releases the slidebar. i kinda hoped that the bitmap would be updated in real-time as the bar is moved, but the image processing class 'Filters' takes about 20 seconds to process a bitmap which is no good. i think i need to work on the latter as i'm sure you should be able to process a bitmap faster than that!:). If this is as fast as AsyncTask can go then i might have to think about drawing the camera bitmap first with no distortion, then create another bitmap overlay where only the circle effect is present. this way the filter cod only has maybe 1/3 of the pixels to loop through? i'll post the code to make sure that it's how you've suggested.</p> <pre><code>import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import com.tecmark.HorizontalSlider.OnProgressChangeListener; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuff.Mode; import android.os.AsyncTask; import android.os.Environment; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class TouchView extends View{ private File tempFile; private byte[] imageArray; private Bitmap bgr; private Bitmap bm; private Bitmap bgr2 = null;; private Paint pTouch; private int centreX = 1; private int centreY = 1; private int radius = 50; private int Progress = 1; private static final String TAG = "*********TouchView"; private Filters f = null; private boolean AsyncRunning = false; private MyTask mt = null; public TouchView(Context context) { super(context); // TouchView(context, null); } public TouchView(Context context, AttributeSet attr) { super(context,attr); tempFile = new File(Environment.getExternalStorageDirectory(). getAbsolutePath() + "/"+"image.jpg"); imageArray = new byte[(int)tempFile.length()]; try{ InputStream is = new FileInputStream(tempFile); BufferedInputStream bis = new BufferedInputStream(is); DataInputStream dis = new DataInputStream(bis); int i = 0; while (dis.available() &gt; 0) { imageArray[i] = dis.readByte(); i++; } dis.close(); } catch (Exception e) { e.printStackTrace(); } BitmapFactory.Options bfo = new BitmapFactory.Options(); bfo.inSampleSize = 1; bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo); bgr = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); bgr = bm.copy(bm.getConfig(), true); bgr2 = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); f = new Filters(); pTouch = new Paint(Paint.ANTI_ALIAS_FLAG); pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)); pTouch.setColor(Color.TRANSPARENT); pTouch.setStyle(Paint.Style.STROKE); }// end of touchView constructor public void findCirclePixels(){ float prog = (float)Progress/150000; bgr2 = f.barrel(bgr,prog); }// end of changePixel() public void initSlider(final HorizontalSlider slider) { // Log.e(TAG, "******setting up slider*********** "); slider.setOnProgressChangeListener(changeListener); } private OnProgressChangeListener changeListener = new OnProgressChangeListener() { @Override public void onProgressChanged(View v, int progress) { // TODO Auto-generated method stub setProgress(progress); //TouchView.this.Progress = progress; if (mt != null) { mt.cancel(true); } mt = new MyTask(); mt.execute(); } }; private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { protected void onPreExecute() { // Log.e(TAG, "***********in PREEXECUTE"); } @Override protected Void doInBackground(Void... params) { // Log.e(TAG, "***********in DOINBACKGROUND"); if(!mt.isCancelled()){ // Log.e(TAG, "***********in doInBackgroud about to call fcp()"); // Log.e(TAG, "***********in doinbackground asyncStatus = "+mt.getStatus()); TouchView.this.findCirclePixels(); Log.e(TAG, "***********in doinbackground fcp() called!!!!"); } return null; } protected void onPostExecute(Void result) { // Log.e(TAG, "***********in POSTEXECUTE"); if(!isCancelled()){ // Log.e(TAG, "***********in postExecute task not canclled and about to invalidate"); // Log.e(TAG, "***********in postexecute asyncStatus = "+mt.getStatus()); TouchView.this.invalidate(); // Log.e(TAG, "***********in postexecute invalidate() called!!!!"); // Log.e(TAG, "***********in postexecute asyncStatus = "+mt.getStatus()); } } }// end of mytask @Override public void onDraw(Canvas canvas){ super.onDraw(canvas); canvas.drawBitmap(bgr2, 0, 0, null); canvas.drawCircle(centreX, centreY, radius,pTouch); }//end of onDraw protected void setProgress(int progress2) { //Log.e(TAG, "***********in SETPROGRESS"); this.Progress = progress2; //Log.e(TAG, "***********in setprogress progress = "+Progress); //Log.e(TAG, "***********in setProgress about to create mytask "); mt = new MyTask(); //Log.e(TAG, "***********in setprogress about to execute mytask"); //Log.e(TAG, "***********in setprogress asyncStatus = "+mt.getStatus()); mt.execute(); // Log.e(TAG, "***********in setprogress asyncStatus = "+mt.getStatus()); // Log.e(TAG, "***********in setprogress mytask executed!!!!! "); } } </code></pre> <p>.</p> <pre><code>@Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP /*|| action == MotionEvent.ACTION_MOVE*/) { float x_mouse = event.getX() - padding; float width = getWidth() - 2*padding; int progress = Math.round((float) getMax() * (x_mouse / width)); if (progress &lt; 0) progress = 0; this.setProgress(progress); if (listener != null) listener.onProgressChanged(this, progress); } return true; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload