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