AsyncTask的应用程序仍然运行缓慢 [英] AsyncTask app still running slowly

查看:221
本文介绍了AsyncTask的应用程序仍然运行缓慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个以位图效果的应用程序。当用户滑动滑块的效应增加/减少失真的水平和位图,然后重绘。我的自定义视图类称为TouchView中和这个类获取位图,并呼吁从过滤器类处理图像的方法。我已经帮助实施的AsyncTask以加快处理了,但无济于事。是AsyncTask的正确实施。感谢马特。

 公共类的TouchView扩展视图{
    私人文件临时文件;
    私人字节[] imageArray;
    私人位图BGR;
    私人位图BM;
    私人位图bgr2 = NULL ;;
    私人涂料pTouch;
    私人INT CENTREX = 1;
    私人INT centreY = 1;
    私人INT半径= 50;
    私人INT进展= 1;
    私有静态最后弦乐TAG =*********的TouchView
    私人过滤器F = NULL;
    私人布尔AsyncRunning = FALSE;    公众的TouchView(上下文的背景下){
        超级(上下文);
       //的TouchView(背景下,NULL);
    }
    公众的TouchView(上下文的背景下,ATTR的AttributeSet){
        超(背景下,ATTR);     //.....$c$c从摄像头和SD卡获取位图        BM = BitmapFactory.de codeByteArray的(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 =新的过滤器();    } //构造的TouchView结束
    公共无效findCirclePixels(){        //设置失真水平
        浮PROG =(浮点)进度/ 15万;        //位图呼叫处理方法
        bgr2 = f.barrel(BGR,PROG);
        } // changePixel结束()    } // onTouchEvent结束    公共无效initSlider(最终水平滑滑块)
    {
        Log.e(TAG,******设置滑块***********);
        slider.setOnProgressChangeListener(的ChangeListener);
    }    私人OnProgressChangeListener的ChangeListener =新OnProgressChangeListener(){
        @覆盖
        公共无效onProgressChanged(视图V,INT进展){
            // TODO自动生成方法存根            setProgress(进度);            Log.e(TAG,***********进度=+进展);        }
    };    私有类MyTask扩展的AsyncTask<太虚,太虚,太虚> {
          在preExecute保护无效(){            }            @覆盖
            保护无效doInBackground(虚空...... PARAMS){
              TouchView.this.findCirclePixels();
              返回null;            }            保护无效onPostExecute(虚空结果){
              TouchView.this.invalidate();
            }
        }
    @覆盖
    公共无效的onDraw(帆布油画){
        super.onDraw(画布);
        canvas.drawBitmap(bgr2,0,0,NULL);
    } //的onDraw结束
    保护无效setProgress(INT progress2){
        this.Progress = progress2;
        新MyTask()执行();
    }
}

[更新]
这是我现在得到。该应用现已不幸较慢运行。你有什么意见,我可以试试吗?

 公共类的TouchView扩展视图{
    私人文件临时文件;
    私人字节[] imageArray;
    私人位图BGR;
    私人位图BM;
    私人位图bgr2 = NULL ;;
    私人涂料pTouch;
    私人INT CENTREX = 1;
    私人INT centreY = 1;
    私人INT半径= 50;
    私人INT进展= 1;
    私有静态最后弦乐TAG =*********的TouchView
    私人过滤器F = NULL;
    私人布尔AsyncRunning = FALSE;
    私人MyTask MT = NULL;    公众的TouchView(上下文的背景下){
        超级(上下文);
       //的TouchView(背景下,NULL);
    }
    公众的TouchView(上下文的背景下,ATTR的AttributeSet){
        超(背景下,ATTR);
        TEMPFILE =新的文件(Environment.getExternalStorageDirectory()。
                getAbsolutePath()+/\"+\"image.jpg);        imageArray =新的字节[(INT)tempFile.length()];
     尝试{            InputStream为=新的FileInputStream(临时文件);
            二BufferedInputStream为=新的BufferedInputStream(是);
            DataInputStream以解散=新DataInputStream所(之二);
            INT I = 0;            而(dis.available()大于0){
            imageArray [I] = dis.readByte();
            我++;
            }            透露();       }赶上(例外五){               e.printStackTrace();
            }        BitmapFactory.Options BFO =新BitmapFactory.Options();
        bfo.inSampleSize = 1;        BM = BitmapFactory.de codeByteArray的(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 =新的过滤器();
    } //构造的TouchView结束
    公共无效findCirclePixels(){
        浮PROG =(浮点)进度/ 15万;
        bgr2 = f.barrel(BGR,PROG);
        } // changePixel结束()    公共无效initSlider(最终水平滑滑块)
    {
        Log.e(TAG,******设置滑块***********);
        slider.setOnProgressChangeListener(的ChangeListener);
    }    私人OnProgressChangeListener的ChangeListener =新OnProgressChangeListener(){
        @覆盖
        公共无效onProgressChanged(视图V,INT进展){
            // TODO自动生成方法存根            setProgress(进度);            Log.e(TAG,***********进度=+进展);        }
    };    私有类MyTask扩展的AsyncTask<太虚,太虚,太虚> {
          在preExecute保护无效(){            }            @覆盖
            保护无效doInBackground(虚空...... PARAMS){
              TouchView.this.findCirclePixels();              返回null;            }            保护无效onPostExecute(虚空结果){                而(!isCancelled()){
              TouchView.this.invalidate();
                }
                     mt.cancel(真);
            }
        }
    @覆盖
    公共无效的onDraw(帆布油画){
        super.onDraw(画布);
        canvas.drawBitmap(bgr2,0,0,NULL);
        canvas.drawCircle(CENTREX,centreY,半径pTouch);    } //的onDraw结束
    保护无效setProgress(INT progress2){
        this.Progress = progress2;
        MT =新MyTask();
        mt.execute();
        AsyncRunning = TRUE;
    }
}

[更新2]

 进口android.content.Context;
进口android.util.AttributeSet;
进口android.view.MotionEvent;
进口android.view.View;
进口android.widget.ProgressBar;公共类水平滑扩展进度{    私人OnProgressChangeListener侦听器;    私有静态诠释填充= 2;    公共接口OnProgressChangeListener {
        无效onProgressChanged(视图V,INT进度);
    }    / *
    公共水平滑(上下文的背景下,ATTRS的AttributeSet,                            地图inflateParams,诠释defStyle){                    超(背景下,ATTRS,inflateParams,defStyle);            }            公共水平滑(上下文的背景下,ATTRS的AttributeSet,                            地图inflateParams){                    超(背景下,ATTRS,inflateParams,android.R.attr.progressBarStyleHorizo​​ntal);
} * /
    公共水平滑(上下文的背景下){
        超级(上下文);    }
    公共水平滑(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
        // TODO自动生成构造函数存根
    }
    公共无效setOnProgressChangeListener(OnProgressChangeListener L){
        听者=升;
    }    @覆盖
    公共布尔onTouchEvent(MotionEvent事件){        INT行动= event.getAction();        如果(动作== MotionEvent.ACTION_DOWN
                ||行动== MotionEvent.ACTION_MOVE){
            浮x_mouse = event.getX() - 填充;
            浮宽度=的getWidth() - 2 *填充;
            INT进度= Math.round((浮点)GetMax的()*(x_mouse /宽));            如果(进度℃下)
                进度= 0;            this.setProgress(进度);            如果(听众!= NULL)
                listener.onProgressChanged(这一点,进度);        }        返回true;
    }
}

[更新3]

大家好,好,我改变了我的code你amendements并改变了我几行这样的观点是通过增加TouchView.this.invalidate()等等。关于我已经将其设置为水平滑更新检查仅ACTION_UP设置进度时。这种方式,用户可以移动滑杆但是当用户释放滑块的视图只失效。我还挺希望将位图实时更新的酒吧移动,但图像处理类过滤器大约需要20秒来处理位图是没有好处的。我想我需要在后面的工作,因为我敢肯定,你应该能够处理位图比快!:)。如果这是一样快的AsyncTask可以去那么我会去想无失真先绘制相机的位图,然后创建另一个位图覆盖,其中仅圈子效果present。这样的过滤器鳕鱼只有可能的像素以循环的1/3通过?我会后的code,以确保它是你是如何建议的。

 进口java.io.BufferedInputStream中;
进口java.io.DataInputStream中;
进口的java.io.File;
进口java.io.FileInputStream中;
进口的java.io.InputStream;进口com.tecmark.Horizo​​ntalSlider.OnProgressChangeListener;进口android.content.Context;
进口android.graphics.Bitmap;
进口android.graphics.BitmapFactory;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.Paint;
进口android.graphics.PorterDuffXfermode;
进口android.graphics.PorterDuff.Mode;
进口android.os.AsyncTask;
进口android.os.Environment;
进口android.util.AttributeSet;
进口android.util.Log;
进口android.view.MotionEvent;
进口android.view.View;公共类的TouchView扩展视图{
    私人文件临时文件;
    私人字节[] imageArray;
    私人位图BGR;
    私人位图BM;
    私人位图bgr2 = NULL ;;
    私人涂料pTouch;
    私人INT CENTREX = 1;
    私人INT centreY = 1;
    私人INT半径= 50;
    私人INT进展= 1;
    私有静态最后弦乐TAG =*********的TouchView
    私人过滤器F = NULL;
    私人布尔AsyncRunning = FALSE;
    私人MyTask MT = NULL;    公众的TouchView(上下文的背景下){
        超级(上下文);
       //的TouchView(背景下,NULL);
    }
    公众的TouchView(上下文的背景下,ATTR的AttributeSet){
        超(背景下,ATTR);
        TEMPFILE =新的文件(Environment.getExternalStorageDirectory()。
                getAbsolutePath()+/\"+\"image.jpg);        imageArray =新的字节[(INT)tempFile.length()];
     尝试{            InputStream为=新的FileInputStream(临时文件);
            二BufferedInputStream为=新的BufferedInputStream(是);
            DataInputStream以解散=新DataInputStream所(之二);
            INT I = 0;            而(dis.available()大于0){
            imageArray [I] = dis.readByte();
            我++;
            }            透露();       }赶上(例外五){               e.printStackTrace();
            }        BitmapFactory.Options BFO =新BitmapFactory.Options();
        bfo.inSampleSize = 1;        BM = BitmapFactory.de codeByteArray的(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 =新的过滤器();
        pTouch =新的油漆(Paint.ANTI_ALIAS_FLAG);
        pTouch.setXfermode(新PorterDuffXfermode(Mode.SRC_OUT));
        pTouch.setColor(Color.TRANSPARENT);
        pTouch.setStyle(Paint.Style.STROKE);
    } //构造的TouchView结束
    公共无效findCirclePixels(){
        浮PROG =(浮点)进度/ 15万;
        bgr2 = f.barrel(BGR,PROG);
        } // changePixel结束()    公共无效initSlider(最终水平滑滑块)
    {
      // Log.e(TAG,******设置滑块***********);
        slider.setOnProgressChangeListener(的ChangeListener);
    }    私人OnProgressChangeListener的ChangeListener =新OnProgressChangeListener(){
        @覆盖
        公共无效onProgressChanged(视图V,INT进展){
            // TODO自动生成方法存根            setProgress(进度);            //TouchView.this.Progress =进展情况;              如果(MT!= NULL){
                mt.cancel(真);
              }              MT =新MyTask();
              mt.execute();
        }
    };    私有类MyTask扩展的AsyncTask<太虚,太虚,太虚> {
          在preExecute保护无效(){
            // Log.e(TAG,***********在preEXECUTE);
            }            @覆盖
            保护无效doInBackground(虚空...... PARAMS){
            // Log.e(TAG,***********在DOINBACKGROUND);
                如果(!mt.isCancelled()){
            // Log.e(TAG,***********在doInBackgroud准备打电话给FCP());
            // Log.e(TAG***********在doinbackground asyncStatus =+ mt.getStatus());
              TouchView.this.findCirclePixels();
              Log.e(TAG,***********在doinbackground FCP()称为!!!!);
                }              返回null;            }            保护无效onPostExecute(虚空结果){
            // Log.e(TAG,***********在POSTEXECUTE);
                如果(!isCancelled()){
           // Log.e(TAG,***********在postExecute任务不canclled和即将失效);
          // Log.e(TAG***********在postexecute asyncStatus =+ mt.getStatus());
              TouchView.this.invalidate();
          // Log.e(TAG,***********在postexecute无效()称为!!!!);
           // Log.e(TAG***********在postexecute asyncStatus =+ mt.getStatus());
                }
            }        } // mytask结束
    @覆盖
    公共无效的onDraw(帆布油画){
        super.onDraw(画布);
        canvas.drawBitmap(bgr2,0,0,NULL);
        canvas.drawCircle(CENTREX,centreY,半径pTouch);    } //的onDraw结束
    保护无效setProgress(INT progress2){
        //Log.e(TAG***********在SETPROGRESS);
        this.Progress = progress2;        //Log.e(TAG,***********在setprogress进度=+进展);        //Log.e(TAG,***********在setProgress要创建mytask);
        MT =新MyTask();
        //Log.e(TAG,***********在setprogress即将执行mytask);
        //Log.e(TAG***********在setprogress asyncStatus =+ mt.getStatus());
        mt.execute();
    // Log.e(TAG***********在setprogress asyncStatus =+ mt.getStatus());
    // Log.e(TAG,***********在执行setprogress mytask !!!!!);    }
}

  @覆盖
    公共布尔onTouchEvent(MotionEvent事件){        INT行动= event.getAction();        如果(动作== MotionEvent.ACTION_UP
                / * ||行动== MotionEvent.ACTION_MOVE * /){
            浮x_mouse = event.getX() - 填充;
            浮宽度=的getWidth() - 2 *填充;             INT进度= Math.round((浮点)GetMax的()*(x_mouse /宽));            如果(进度℃下)
                进度= 0;            this.setProgress(进度);            如果(听众!= NULL)
                listener.onProgressChanged(这一点,进度);
        }
        返回true;
    }
}


解决方案

看来,在你的滑块每个值的变化,你正在创建你的 MyTask 并运行它。相反,滑块已经发布时可能有更好的表现只更新您的听众有一件事(停止移动)。它看起来像水平滑是一个自定义类,所以我不能对正在发生的事情在那里说话。

如果滑块正在从左至右移动,它可能是在移动过程中断火更新事件100倍。这将是100后台任务!

更新

一种可能性是取消()您的活动 MyTask 你产生另外一个之前。如果拿这条路线,你需要调用 isCancelled() onPostExecute 且仅当该任务是无效视图的取消。但是,如果在 findCirclePixels的code()是瓶颈,这是不行的。我的猜测是,创建一个新的前取消活动任务将不会您解决问题。

此编码正确(仅创建 MyTask 必要时)仍然将是最好的途径。考虑到每的AsyncTask 操作系统必须生成一个新的后台线程,它带有自己的开销。不要$ C $少量被愚弄c您已经把 doInBackground()

再次更新

我已经清理你的code和增加了对建议意见:

 公共类的TouchView扩展视图{  私人文件临时文件;
  私人字节[] imageArray;
  私人位图BGR;
  私人位图BM;
  私人位图bgr2 = NULL ;;
  私人涂料pTouch;
  私人INT CENTREX = 1;
  私人INT centreY = 1;
  私人INT半径= 50;
  私人INT进展= 1;
  私有静态最后弦乐TAG =*********的TouchView
  私人过滤器F = NULL;
  私人MyTask MT = NULL;  公众的TouchView(上下文的背景下){
    超级(上下文);
  }  公众的TouchView(上下文的背景下,ATTR的AttributeSet){
    超(背景下,ATTR);    TEMPFILE =新的文件(Environment.getExternalStorageDirectory()。
            getAbsolutePath()+/\"+\"image.jpg);
    imageArray =新的字节[(INT)tempFile.length()];    尝试{
      InputStream为=新的FileInputStream(临时文件);
      二BufferedInputStream为=新的BufferedInputStream(是);
      DataInputStream以解散=新DataInputStream所(之二);      INT I = 0;
      而(dis.available()大于0){
        imageArray [I] = dis.readByte();
        我++;
      }      透露();
    }赶上(例外五){
      e.printStackTrace();
    }    BitmapFactory.Options BFO =新BitmapFactory.Options();
    bfo.inSampleSize = 1;    BM = BitmapFactory.de codeByteArray的(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 =新的过滤器();
  }  公共无效findCirclePixels(){
    浮PROG =(浮点)进度/ 15万;
    bgr2 = f.barrel(BGR,PROG);
  }  公共无效initSlider(最终水平滑滑块){
    slider.setOnProgressChangeListener(的ChangeListener);
  }  私人OnProgressChangeListener的ChangeListener =新OnProgressChangeListener(){
    @覆盖
    公共无效onProgressChanged(视图V,INT进展){
      / *
      TODO:如果有一种方法,以查看是否在滑块仍在改变(控制
      尚未发布),那么你就应该返回,而不是继续
      创建另一个任务
      * /      this.Progress = progress2;      如果(MT!= NULL){
        mt.cancel();
      }      MT =新MyTask();
      mt.execute();
    }
  };  私有类MyTask扩展的AsyncTask<太虚,太虚,太虚> {
      在preExecute保护无效(){
      }      @覆盖
      保护无效doInBackground(虚空...... PARAMS){
        //这个检查是没有必要的,如果$ C $正确的CD
        如果(!isCancelled()){
          TouchView.this.findCirclePixels();
        }
        返回null;
      }      保护无效onPostExecute(虚空结果){
        //这个检查是没有必要的,如果$ C $正确的CD
        如果(!isCancelled()){
          TouchView.this.invalidate();
        }
      }
  }
  @覆盖
  公共无效的onDraw(帆布油画){
    super.onDraw(画布);    canvas.drawBitmap(bgr2,0,0,NULL);
    canvas.drawCircle(CENTREX,centreY,半径pTouch);
  }
}

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.

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<Void, Void, Void> {
          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();


    }




}

.

[update] This is what i've got now. The app is running slower now unfortunately. Have you any further ideas that i could try?

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() > 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<Void, Void, Void> {
          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;


    }




}

.

[update 2]

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 < 0)
                progress = 0;

            this.setProgress(progress);

            if (listener != null)
                listener.onProgressChanged(this, progress);

        }

        return true;
    }
}

.

[update 3]

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.

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() > 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<Void, Void, Void> {
          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!!!!! ");



    }




}

.

@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 < 0)
                progress = 0;

            this.setProgress(progress);

            if (listener != null)
                listener.onProgressChanged(this, progress);
        }


        return true;
    }
}

解决方案

It appears that for every value change in your slider, you are creating your MyTask and running it. Instead, one thing that might perform better is only updating your listener when the slider has been released (stopped moving). It looks like HorizontalSlider is a custom class, so I can't speak for what is happening in there.

If a slider is being moved from left to right, it may fire off update events 100 times during that move. That would be 100 background tasks!

UPDATE

One possibility would be to cancel() your active MyTask before you produce another one. If you take that route you need to call isCancelled() in onPostExecute and only invalidate your view if the task is not cancelled. However, if the code in findCirclePixels() is the bottleneck, this will not work. My guess is that cancelling the active task before creating a new one will NOT solve your problem.

Coding this up properly (only creating your MyTask when necessary) is still going to be the best route. Consider that for every AsyncTask the OS has to spawn a new background thread, which comes with its own overhead. Don't be fooled by the small amount of code you have put in doInBackground().

UPDATE AGAIN

I have cleaned up your code and added comments for suggestion:

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 MyTask mt = null;

  public TouchView(Context context) {
    super(context);
  }

  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() > 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();
  }

  public void findCirclePixels(){ 
    float prog = (float) Progress / 150000;
    bgr2 = f.barrel(bgr, prog);
  }

  public void initSlider(final HorizontalSlider slider) {
    slider.setOnProgressChangeListener(changeListener);
  }

  private OnProgressChangeListener changeListener = new OnProgressChangeListener() {
    @Override
    public void onProgressChanged(View v, int progress) {
      /*
      TODO: If there is a way to see if the slider is still being changed (control
      has not been released), then you should return and not continue with the
      creation of another task
      */

      this.Progress = progress2;

      if (mt != null) {
        mt.cancel();
      }

      mt = new MyTask();
      mt.execute();
    }
  };

  private class MyTask extends AsyncTask<Void, Void, Void> {
      protected void onPreExecute() {
      }

      @Override
      protected Void doInBackground(Void... params) {
        // This check is not necessary if coded properly
        if (!isCancelled()) {
          TouchView.this.findCirclePixels();
        }
        return null;
      }

      protected void onPostExecute(Void result) { 
        // This check is not necessary if coded properly
        if (!isCancelled()) {
          TouchView.this.invalidate();
        }
      }
  }




  @Override
  public void onDraw(Canvas canvas){
    super.onDraw(canvas);

    canvas.drawBitmap(bgr2, 0, 0, null);
    canvas.drawCircle(centreX, centreY, radius, pTouch);
  }
}

这篇关于AsyncTask的应用程序仍然运行缓慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆