Mam aplikację, która pobiera obraz z kamery i umieszcza efekt zniekształcenia rybiego oka na mapie bitowej. Zastosowanie efektu i przerysowanie mapy bitowej zajmuje około 20 sekund. postanowiłem zaimplementować program obsługi, aby przyspieszyć przetwarzanie w drugim wątku. kod obsługi wydaje się nie mieć wpływu na aplikację. Zasadniczo, gdy suwak jest przesuwany przez użytkownika, bardziej zniekształca to mapę bitową. istnieje znaczne opóźnienie między przesuwaniem paska sldebar a przerysowaniem(). Czy poprawnie to zaimplementowałem? dzięki mat.

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
turtleboy 8 czerwiec 2011, 23:00

2 odpowiedzi

Najlepsza odpowiedź

Powinieneś używać AsyncTask. Program obsługi jest powiązany z wątkiem, który go tworzy, więc Twój program obsługi jest nadal powiązany z wątkiem interfejsu użytkownika.

2
Ravi Vyas 8 czerwiec 2011, 23:09
Vyas, pamiętam, że teraz to czytałem, dzięki. Próbowałem spojrzeć na AsyncTask, ale nie jestem pewien, jak zastosować go do mojej aplikacji. opublikuję kolejne pytanie.
 – 
turtleboy
8 czerwiec 2011, 23:13

Ponieważ nie dostarczyłeś całego odpowiedniego kodu, trudno jest uzyskać wszystkie szczegóły, ale oto problemy z twoim kodem, które mogłem zobaczyć.

  1. Program obsługi w twoim przypadku powinien być używany tylko do aktualizacji interfejsu użytkownika po zakończeniu operacji. Rzeczywista praca musi być wykonana w wątku w tle, a nie w module obsługi.
  2. Tworzysz i uruchamiasz nowy wątek z progressListener. Możesz więc skończyć z wieloma wątkami wykonującymi tę samą pracę.

Możesz lub nie możesz używać AsyncTask, jak sugeruje inny post (chociaż to dobry pomysł), ale używaj programu obsługi tylko do aktualizacji interfejsu użytkownika po zakończeniu pracy.

0
Alex Gitelman 8 czerwiec 2011, 23:20