处理程序没有加速辅助线程中的应用程序

时间:2011-06-08 19:00:01

标签: android multithreading bitmap handler

我有一个应用程序,它采用相机图像并在位图上放置鱼眼失真效果。应用效果并重绘位图大约需要20秒以上。我决定实现一个处理程序来加速第二个线程的处理。处理程序代码似乎对应用程序没有影响。基本上,当用户移动滑动条时,这会更多地扭曲位图。 sldebar移动和重绘()之间有明显的滞后。我正确地补充了这个吗?谢谢亚光。

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;
    private static final String TAG = "*********TouchView";
    private Filters f = null;

    private Handler handler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

        super.handleMessage(msg);



        }

        };

    public TouchView(Context context) {
        super(context);
       // TouchView(context, null);
    }




    public TouchView(Context context, AttributeSet attr) {
        super(context,attr);



     //......code that loads bitmap from sdcard

        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(){ 



        Log.e(TAG, "inside fcp()");
        float prog = (float)Progress/150000;
        bgr2 = f.barrel(bgr,prog);


        }// end of changePixel()




    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

            case MotionEvent.ACTION_DOWN: {

                centreX = (int) ev.getX();
                centreY = (int) ev.getY();
                findCirclePixels();
                invalidate();

                break;
            }

            case MotionEvent.ACTION_MOVE: {

                    centreX = (int) ev.getX();
                    centreY = (int) ev.getY();
                    findCirclePixels();
                    invalidate();
                    break;

            }           

            case MotionEvent.ACTION_UP: 

                break;

        }
        return true;
    }//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);
            processThread();
            Log.e(TAG, "***********progress = "+Progress);

        }
    };

    private void processThread() {



        new Thread() {

        public void run() {
            Log.e(TAG, "about to call findcirclepixel in new thread");
        findCirclePixels();

        handler.sendEmptyMessage(0);

        }

        }.start();

        }



    @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;
        findCirclePixels();
        invalidate();

    }


}

2 个答案:

答案 0 :(得分:2)

您应该使用AsyncTask。处理程序绑定到创建它的线程,因此您的处理程序仍然绑定到UI线程。

答案 1 :(得分:0)

由于您没有提供所有相关代码,因此很难获得所有详细信息,但这里是您可以看到的代码问题。

  1. 您的案例中的处理程序只应在操作完成后用于更新UI。实际工作必须在后台线程中完成,而不是在处理程序中完成。
  2. 您可以从progressListener创建并启动新的线程。所以你最终可能会有多个线程做同样的工作。
  3. 您可能会或可能不会像其他帖子建议的那样使用AsyncTask(尽管这是个好主意),但只有在工作完成后才使用处理程序来更新UI。