1

I created a simple crossfade image class for use in my app. But... i have an error i can't fix due to lack of knowledge. I found this post This Handler class should be static or leaks might occur: IncomingHandler but i have no clue how to fix this in my class. It is a very straightforward class. Create, initialize and start to use it.

I hope someone can help me fix this warning and while we are at it, some hints and tips on my code or comments are very welcome too ;)

MainActivity.java

package com.example.crossfadeimage;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    Xfade xfade = new Xfade();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // INIT(current activity, image id's, time between fades, fade speed)
        xfade.init(this, new int[]{ R.id.image1, R.id.image2, R.id.image3 }, 3000, 500);
        xfade.start();

    }

}

Xfade.java

package com.example.crossfadeimage;

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.ImageView;

public class Xfade {

    private Activity activity;

    // Handler
    private Handler handlerTimer = new Handler();
    private static final int UPDATE_STUFF_ON_DIALOG = 999;
    private int updateTime;

    private Animation fadeIn;
    private Animation fadeOut;

    public int[] xfadeImages;

    public int xfadeCounter = 1;

    public void init(Activity thisActivity, int[] images, int time,
            int animationSpeed) {

        activity = thisActivity;
        xfadeImages = images;
        updateTime = time;

        // Set Animations
        fadeIn = new AlphaAnimation(0, 1);
        fadeIn.setDuration(animationSpeed);

        fadeOut = new AlphaAnimation(1, 0);
        fadeOut.setDuration(animationSpeed);

        // Hide all images except the first
        // which is always visible
        for (int image = 1; image < xfadeImages.length; image++) {

            ImageView thisImage = (ImageView) activity
                    .findViewById(xfadeImages[image]);
            thisImage.setVisibility(4);

        }

    }

    public void start() {

        handlerTimer.removeCallbacks(taskUpdateStuffOnDialog);
        handlerTimer.postDelayed(taskUpdateStuffOnDialog, updateTime);

    }

    private Runnable taskUpdateStuffOnDialog = new Runnable() {
        public void run() {

            Message msg = new Message();
            msg.what = UPDATE_STUFF_ON_DIALOG;
            handlerEvent.sendMessage(msg);

            // Repeat this after 'updateTime'
            handlerTimer.postDelayed(this, updateTime);
        }
    };

    private Handler handlerEvent = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case UPDATE_STUFF_ON_DIALOG: {
                crossFade();
            }
                break;
            default: {
                super.handleMessage(msg);
            }
                break;
            }
        }
    };

    public void crossFade() {

        if (xfadeCounter == 0) {
            ImageView lastImage = (ImageView) activity
                    .findViewById(xfadeImages[xfadeImages.length - 1]);
            lastImage.setVisibility(4);
        }

        if (xfadeCounter < xfadeImages.length) {

            ImageView thisImage = (ImageView) activity
                    .findViewById(xfadeImages[xfadeCounter]);
            thisImage.setVisibility(0);
            thisImage.startAnimation(fadeIn);

            xfadeCounter++;

        } else {

            // Hide all images except the first
            // before fading out the last image
            for (int image = 1; image < xfadeImages.length; image++) {

                ImageView thisImage = (ImageView) activity
                        .findViewById(xfadeImages[image]);
                thisImage.setVisibility(4);

            }

            // Fadeout
            ImageView lastImage = (ImageView) activity
                    .findViewById(xfadeImages[xfadeImages.length - 1]);
            lastImage.startAnimation(fadeOut);

            // LastImage is faded to alpha 0 so it doesn't have to be hidden
            // anymore
            xfadeCounter = 1;

        }

    }

}
Community
  • 1
  • 1
Switching Brains
  • 290
  • 4
  • 15

1 Answers1

3

This allows you to modify views and have your handler set to static.

package com.testing.test;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class MainActivity extends Activity implements Runnable {

    private static final int THREAD_RESULT = 1000;

    private TextView mTextView;

    private static Handler mHandler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = (TextView) findViewById(R.id.text);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mHandler = new CustomHandler(this);
        new Thread(this).start();
    }

    @Override
    public void run() {

        // Do some threaded work

        // Tell the handler the thread is finished
        mHandler.post(new Runnable() {

            @Override
            public void run() {
                mHandler.sendEmptyMessage(THREAD_RESULT);
            }
        });
    }

    private class CustomHandler extends Handler {

        private MainActivity activity;

        public CustomHandler(MainActivity activity) {
            super();
            this.activity = activity;
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case THREAD_RESULT:
                activity.mTextView.setText("Success!");
                break;
            }
        }

    }

}
ian.shaun.thomas
  • 3,468
  • 25
  • 40
  • Tried this but i get tons of 'Cannot make a static reference to the non-static field' errors then. I cant make them al static? – Switching Brains Aug 31 '12 at 08:14
  • Ahh right, updated my answer for you. Really you might want to consider using async tasks instead. To me, they make more sense and are easier to read and understand when implemented. http://developer.android.com/reference/android/os/AsyncTask.html – ian.shaun.thomas Aug 31 '12 at 11:59
  • @tencent I'm not sure what the Runnable interface is for here? I tried to copy your pattern (except for the Runnable): https://gist.github.com/daviddoria/f31699ca492d5d368766 but I still get the "Handler class should be static" on the IncomingHandler constructor? – David Doria Oct 02 '13 at 12:15