обработчик не ускоряет работу приложения во вторичном потоке

#android #multithreading #bitmap #handler

#Android #многопоточность #растровое изображение #обработчик

Вопрос:

У меня есть приложение, которое снимает изображение с камеры и накладывает эффект искажения «рыбий глаз» на растровое изображение. Для применения эффекта и перерисовки растрового изображения требуется более 20 секунд. я решил внедрить обработчик для ускорения обработки во втором потоке. код обработчика, похоже, не влияет на приложение. В основном, когда пользователь перемещает ползунок, это еще больше искажает растровое изображение. существует значительная задержка между перемещением ползунка и перерисовкой (). Правильно ли я это выполнил? спасибо, Мэтт.

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

    }


}
  

Ответ №1:

Вы должны использовать AsyncTask . Обработчик привязан к потоку, создающему его, поэтому ваш обработчик по-прежнему привязан к потоку пользовательского интерфейса.

Комментарии:

1. Вьяс, я помню, что читал это сейчас, спасибо. Я пытался посмотреть на AsyncTask, но не уверен, как применить его к моему приложению. я опубликую другой вопрос.

Ответ №2:

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

  1. Обработчик в вашем случае следует использовать только для обновления пользовательского интерфейса после завершения операции. Фактическая работа должна выполняться в фоновом потоке, а не в обработчике.
  2. Вы создаете и запускаете новый поток из ProgressListener. Таким образом, вы можете столкнуться с несколькими потоками, выполняющими одну и ту же работу.

Вы можете использовать, а можете и не использовать AsyncTask , как предлагает другой пост (хотя это хорошая идея), но используйте обработчик только для обновления пользовательского интерфейса после выполнения задания.