Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing context to Handler

Is it possible to pass arguments to an Android Handler?? I have two pieces of code.

new Thread(){
        public void run(){
            for(;;){
                uiCallback.sendEmptyMessage(0);
                Thread.sleep(2000); //sleep for 2 seconds
            }
        }
    }.start();


    private Handler uiCallback = new Handler(){
    public void handleMessage(Message msg){
        //add a new blossom to the blossom ArrayList!!
        blossomArrayList.add(new Blossom(context, R.drawable.blossom));
    }
};

I of course get an error because the Handler method cannot see my context. This is probably because of this piece of code

public BoardView(Context context){
    super(context);

Context is not visible elsewhere, and I'm wondering if I can pass it as an argument to my Handler.

EDIT: I am posting the two main pieces of code to answer a question about why my Blossom object needs context. I myself am not 100% sure >.> Maybe you could have a look and see what's going on.

public class Blossom{
private Bitmap blossom;
private float blossomX = 0;
private float blossomY = 0;
private Random generator = new Random();

public Blossom(Context context, int drawable)
{
    blossom = BitmapFactory.decodeResource(context.getResources(), drawable); 
    blossomX = generator.nextInt(300);
}

public Bitmap getBitmap()
{
    return blossom;
}

public float getBlossomX()
{
    return blossomX;
}

public float getBlossomY()
{
    return blossomY;
}

public void Fall(Canvas canvas, float boxY)
{
    //draws the flower falling
    canvas.drawBitmap(blossom, blossomX,
            blossomY = blossomY+3 , null);

    //collision detection, currently not working after 
    //implementing random start location

    //if(blossomY + 29 == boxY)
    //{
        //canvas.drawBitmap(blossom,0,0,null);
    //}

}
}


public class BoardView extends SurfaceView implements SurfaceHolder.Callback{
Context mContext;

Bitmap box = 
    (BitmapFactory.decodeResource
            (getResources(), R.drawable.box));

private BoardThread thread;
private float box_x = 140;
private float box_y = 378;
private float boxWidth = box.getWidth();
private float boxHeight = box.getHeight();
private ArrayList<Blossom> blossomArrayList = new ArrayList<Blossom>();;

boolean mode = false;

RectF boxRect = new RectF(box_x,box_y, box_x + boxWidth, box_y + boxHeight);

public BoardView(Context context){
    super(context);

    //surfaceHolder provides canvas that we draw on
    getHolder().addCallback(this);

    // controls drawings
    thread = new BoardThread(getHolder(),this);

    //pass variables to instance of Blossom
    //for(int i = 0; i <= 3; i++)
    //{
        //blossomArrayList.add(new Blossom(context, R.drawable.blossom));
    //}

    new Thread(){
        public void run(){
            for(;;){
                uiCallback.sendEmptyMessage(0);
                Thread.sleep(2000); //sleep for 2 seconds
            }
        }
    }.start();

    //intercepts touch events
    setFocusable(true);

}

@Override

public void onDraw(Canvas canvas){
    canvas.drawColor(Color.WHITE);  


    //draw box and set start location
    canvas.drawBitmap(box, box_x - (boxWidth/2), 
            box_y - (boxHeight/2), null);

    for(int i = 0; i<= 3; i++)
    {
        blossomArrayList.get(i).Fall(canvas, box_y);
    }

}

@Override
public boolean onTouchEvent(MotionEvent event){

    if(event.getAction() == MotionEvent.ACTION_DOWN){
        if(boxRect.contains(event.getX(),event.getY())){
            mode = true;
        }
    }

    if(event.getAction() == MotionEvent.ACTION_MOVE) {
        if(boxRect.contains(event.getX(),event.getY())){
            mode = true;
        }
        if(mode == true){
            box_x = (int)event.getX();
            boxRect.set(box_x,box_y, box_x + boxWidth, box_y + boxHeight);
        }

    }

    if(event.getAction() == MotionEvent.ACTION_UP){
        mode = false;
    }

    invalidate();

    return true;
}

@Override
public void surfaceChanged(SurfaceHolder holder, 
        int format, int width, int height ){

}

@Override
public void surfaceCreated(SurfaceHolder holder){
    thread.startRunning(true);
    thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder){
    thread.startRunning(false);
    thread.stop();
}

private Handler uiCallback = new Handler(){
    public void handleMessage(Message msg){
        //add a new blossom to the blossom ArrayList!!
        blossomArrayList.add(new Blossom(context, R.drawable.blossom));
    }
};


}
like image 943
Hani Honey Avatar asked Mar 28 '11 17:03

Hani Honey


People also ask

How do you pass context in handler?

Create a class that extends Handler, and store a weak reference to the context. This will help prevent some memory issues.

What is the purpose of post () method related to a handler?

post. Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.

What is PostDelayed in handler?

PostDelayed(IRunnable, Object, Int64)Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses.

Why do we use handlers?

In android Handler is mainly used to update the main thread from background thread or other than main thread. There are two methods are in handler. Post() − it going to post message from background thread to main thread using looper.


2 Answers

Create a class that extends Handler, and store a weak reference to the context. This will help prevent some memory issues.

public class SomeHandler extends Handler {

    // A weak reference to the enclosing context
    private WeakReference<Context> mContext;

    public SomeHandler (Context context) {
        mContext = new WeakReference<Context>(context);
    }

    public void handleMessage(Message msg) {

        // Get an actual reference to the DownloadActivity
        // from the WeakReference.
        Context context=mContext.get();
        ...
    }
}
like image 113
PearsonArtPhoto Avatar answered Sep 28 '22 05:09

PearsonArtPhoto


What if you create a subclass which extends Handler? That way you could pass any parameters you want.

But just out of curiosity, why does the Blossom object require the context object? It's usually best to separate your logic from GUI dependencies.

like image 30
kkudi Avatar answered Sep 28 '22 03:09

kkudi