0

xhdpiおよびldpiデバイスで完全に動作するライブ壁紙アプリを作成していますが、hdpiおよびmdpiベースのハンドセットで強制終了の問題が発生します。

「壁紙の設定」をクリックするとプレビュー画面に画像が読み込まれ、アプリから設定を変更してもクラッシュします。

上記の 2 つの条件により、アプリが強制終了されます。

OutOfMemoryErrorのように見えます

エラーに一貫性がありません

これが私のコードです:

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

    }

}

}

pixelthree クラスは示していませんが、この問題を解決するには 2 つのクラスで十分だと思います。

任意のヘルプをいただければ幸いです。

ありがとう

4

2 に答える 2

1

メモリ不足エラーのようです。ビットマップのメモリを減らしてみてください。これをチェックすると、ビットマップの最適化に役立ちます。

于 2012-08-29T05:20:05.553 に答える
0

サンプルサイズを2に減らしてみましたが、うまくいきました..

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

options.inSampleSize = 2;

options.inPurgeable = true
于 2012-10-05T12:15:50.157 に答える