Передача контекста в обработчик - PullRequest
4 голосов
/ 28 марта 2011

Можно ли передать аргументы в обработчик Android ??У меня есть две части кода.

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

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

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

Контекст не виден в другом месте, и мне интересно, могу ли я передать его в качестве аргумента моему обработчику.

РЕДАКТИРОВАТЬ: Iя публикую два основных фрагмента кода, чтобы ответить на вопрос о том, зачем моему объекту Blossom нужен контекст.Я сам не уверен на 100%>.> Может быть, вы могли бы взглянуть и посмотреть, что происходит.

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


}

Ответы [ 2 ]

3 голосов
/ 13 июня 2014

Создайте класс, расширяющий Handler, и сохраните слабую ссылку на контекст. Это поможет предотвратить некоторые проблемы с памятью.

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();
        ...
    }
}
3 голосов
/ 28 марта 2011

Что если вы создадите подкласс, который расширяет Handler?Таким образом, вы можете передать любые параметры, какие захотите.

Но просто из любопытства, почему объекту Blossom требуется объект контекста?Обычно лучше отделить вашу логику от зависимостей GUI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...