Search code examples
bitmaplive-wallpaper

Live wallpaper getting force close issue


I am creating live wallpaper app, that runs perfectly on xhdpi and ldpi device, but getting force close issue in hdpi and mdpi based handset.

It loads image in preview screen when we click "set wallpaper" it get crashed and even when we change settings from app.

Above two conditions make app to force close.

Looks like OutOfMemoryError

Error is not consistent

Here is my code :

pixeltwo.java

public class pix11two extends SurfaceView {
private pix11three three;
int fps;
Bitmap mBitmap;
int country_flag;

public pix11two(Context context, int fps, int country) {
    super(context);
    this.fps = fps;

    country_flag = country;

    DisplayMetrics displayMetrics = new DisplayMetrics();
    displayMetrics = context.getResources().getDisplayMetrics();
    int displayWidth = displayMetrics.widthPixels;
    int displayHeight = displayMetrics.heightPixels;

    if (mBitmap != null)
        mBitmap.recycle();

    BitmapFactory.Options options = new BitmapFactory.Options();

    options.inSampleSize = 1;

    options.inPurgeable = true;

    if (country_flag > 1) {

        if (country_flag == 2) {

            mBitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.yellow, options);
        }

        if (country_flag == 3) {

            mBitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.orange, options);
        }

        if (country_flag == 4) {

            mBitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.green, options);
        }

        if (country_flag == 5) {

            mBitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.red, options);
        }
        if (country_flag == 6) {
            mBitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.purple, options);
        }

        if (country_flag == 7) {
            mBitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.pink, options);
        }

    } else {

        mBitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.blue, options);
    }

    three = new pix11three(mBitmap, displayWidth, displayHeight, 0, 0, fps,
            10);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        // handle touch
    }
    return true;
}

public void render(Canvas canvas) {
    canvas.drawColor(Color.BLACK);
    three.draw(canvas);
}

public void update() {
    three.update(System.currentTimeMillis());
}

}

pixelone.java

    public class pix11one extends WallpaperService {
public static final String SHARED_PREFS_NAME = "animation";

@Override
public void onCreate() {
    super.onCreate();
}

@Override
public void onDestroy() {
    super.onDestroy();
}

@Override
public Engine onCreateEngine() {
    return new pix11engine();
}

class pix11engine extends Engine implements
        SharedPreferences.OnSharedPreferenceChangeListener {

    boolean mVisible = false;

    pix11two two;

    pix11three three;

    int country_counter = 1;

    private final Handler mHandler = new Handler();

    private final Runnable mDrawPattern = new Runnable() {
        public void run() {

            draw();
        }
    };
    SharedPreferences mPrefs;

    public pix11engine() {

        mPrefs = pix11one.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
        mPrefs.registerOnSharedPreferenceChangeListener(this);
        onSharedPreferenceChanged(mPrefs, null);
    }

    public void onSharedPreferenceChanged(SharedPreferences prefs,
            String key) {

        String speed = prefs.getString("animate_speed", "one");

        String country_flag = prefs.getString("country", "English");

        String country_values[] = getResources().getStringArray(
                R.array.country_values);

        // Comparing with preference value and array value

        for (int i = 0; i < country_values.length; i++) {

            if (country_values[i].equalsIgnoreCase(country_flag)) {

                country_counter = i + 1;

            }

        }

        if (speed.equals("one")) {

            // Default
            two = new pix11two(getBaseContext(), 7, country_counter);

            draw();

        } else if (speed.equals("two")) {

            // Slowest
            two = new pix11two(getBaseContext(), 2, country_counter);
            draw();
        } else if (speed.equals("three")) {

            // Slow
            two = new pix11two(getBaseContext(), 4, country_counter);
            draw();
        } else if (speed.equals("four")) {

            // Fast

            two = new pix11two(getBaseContext(), 14, country_counter);
            draw();
        } else if (speed.equals("five")) {

            // Fastest

            two = new pix11two(getBaseContext(), 18, country_counter);
            draw();
        }
    }

    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {
        super.onCreate(surfaceHolder);
        setTouchEventsEnabled(true);
    }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
        super.onSurfaceDestroyed(holder);
        mVisible = false;
        mHandler.removeCallbacks(mDrawPattern);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacks(mDrawPattern);
    }

    @Override
    public void onVisibilityChanged(boolean visible) {
        mVisible = visible;
        if (visible) {
            draw();
        } else {
            mHandler.removeCallbacks(mDrawPattern);
        }
    }

    @Override
    public void onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {

        }
        super.onTouchEvent(event);
    }

    private void draw() {
        final SurfaceHolder holder = getSurfaceHolder();
        Canvas c = null;
        try {
            c = holder.lockCanvas();
            if (c != null) {

                two.render(c);
                two.update();
            }
        } catch (Exception e) {
        } finally {
            if (c != null)
                holder.unlockCanvasAndPost(c);
        }
        mHandler.removeCallbacks(mDrawPattern);
        if (mVisible) {
            mHandler.postDelayed(mDrawPattern, 1000 / 75);
        }

    }

}

}

I havent shown pixelthree class, but i think two class are sufficent to solve the issue.

Any Help would be appreciated.

Thanks


Solution

  • I have tried by decreasing sample size to 2 and it worked for me..

    BitmapFactory.Options options = new BitmapFactory.Options();

    options.inSampleSize = 2;
    
    options.inPurgeable = true