handler not speeding up app in secondary thread
I've an app开发者_JAVA百科 that takes a camera image and places a fisheye distortion effect on the bitmap. It takes about 20+ seconds to apply the effect and redraw the bitmap. i decided to implemnt a handler to speed the processing up in a second thread. the handler code seems to have no affect on the app. Basically when the slidebar is moved by the user this distorts the bitmap more. there is significant lag between the sldebar moving nd the redraw(). Have i iplemented this correctly? 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;
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();
}
}
You should be using an AsyncTask . A handler is bound to the thread creating it so your handler is still bound to the UI thread.
Since you didn't provide all relevant code it's hard to get all details but here are issues with you code that I could see.
- Handler in your case should only be used to update UI after operation is done. Actual job must be done in background thread, not in handler.
- You create and start new Thread from progressListener. So you may end up with multiple threads doing the same job.
You may or may not use AsyncTask
as other post suggests (although it is good idea), but only use handler to update UI after job is done.
精彩评论