Passing context to Handler
Solution 1
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.
Solution 2
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();
...
}
}
Hani Honey
Updated on June 04, 2022Comments
-
Hani Honey almost 2 years
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)); } }; }
-
Hani Honey about 13 yearsI have posted the rest of my code so you can see what is going on with the context. I honestly have no idea :(
-
Hani Honey about 13 yearsIt was the only way I could figure out how to get a bitmap into my Blossom class, that's why.
-
kkudi about 13 yearsWell your Blossom constructor could just take the bitmap instead. But nevertheless, what you want can be achieved by just creating a new class say MyHandler which extends Handler and create a constructor public MyHandler(Context context) {....}
-
Hani Honey about 13 yearsThank you - I just passed it the bitmap and it was fine :D Why didn't I do that in the first place...
-
hidd almost 5 yearsVery useful. Thanks a lot.