3

所以我是 Java 和这种编码的新手。

我正在尝试制作视差滚动动态壁纸。但我有记忆问题。

好吧,我已经成功了,它可以在我拥有的手机上运行。但我认为我这样做的方式根本不是很有效。因为当我在其他手机上尝试时,它不起作用。它打破了我的内存不足捕手。我添加了另一层,现在它也在我的手机上做同样的事情。所以我可以调试它。基本上我想我正在使用高达或超过 16 兆的内存。

如果有人可以查看我的代码并帮助我更有效地加载位图,将不胜感激。

这是我目前的做法:

static class Layer {
    public Bitmap bitmap;
    private float scale = 1.0f;
    private Matrix matrix = new Matrix();
    public Layer(Bitmap b) {
        this.bitmap = b;
    }
    public void setScale(float factor) {
        scale = factor;
    }
    public Matrix getMatrix(float x, float y) {
        if (scale == 1) {
            matrix.reset();
        } else {
            matrix.setScale(scale, scale);
        }
        matrix.postTranslate(x, y);
        return matrix;
    }
}

public static List<Integer> findLayers(Integer path) {

    List<Integer> files = new ArrayList<Integer>();


    files.add(R.drawable.planet_layer4);
    files.add(R.drawable.planet_layer3);
    files.add(R.drawable.planet_layer2);
    files.add(R.drawable.planet_layer1);    
    files.add(R.drawable.planet_layer0);

    return files;
}   



    private void loadLayers() {
        try {
            clearLayers();
            for (Integer file: layerFiles) {
                addLayer(file);
            }
            recalibrateLayers();
        } catch (IOException e) {
            layers.clear();
            Toast.makeText(LiveWallpaper.this, "There was a problem loading the wallpaper. Please contact the developer.", Toast.LENGTH_LONG).show();
        } catch (OutOfMemoryError oom) {
            layers.clear();
            Toast.makeText(LiveWallpaper.this, "Whoops, we ran out of memory trying to load the images. ", Toast.LENGTH_LONG).show();
        }
    }

    private void addLayer(int name) throws IOException {
        Bitmap layer = BitmapFactory.decodeResource(getResources(), name);
        if (layer == null) {
            throw new IOException("BitmapFactory couldn't decode asset " + name);
        }
        synchronized(layers) {
            layers.add(new Layer(layer));
        }
    }

    private void clearLayers() {
        synchronized(layers) {
            layers.clear();
        }
    }

    private void recalibrateLayers() {
        for (Layer layer : layers) {
            final int bitmapHeight = layer.bitmap.getHeight();
            layer.setScale((float)mHeight / (float)bitmapHeight);
        }
    }

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


    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        super.onSurfaceChanged(holder, format, width, height);

        mHeight = height;

        recalibrateLayers();

        drawBackgrounds();

    }

这是我画它们的地方。

/*
     * Draw one frame of the animation. This method gets called repeatedly
     * by posting a delayed Runnable. You can do any drawing you want in
     * here.
     */
    void drawBackgrounds() {
        final SurfaceHolder holder = getSurfaceHolder();
        final Rect frame = holder.getSurfaceFrame();

        mFrame = frame;

        Canvas c = null;
        try {
            c = holder.lockCanvas();
            if (c != null) {
                // draw something
                drawParallax(c);
            }
        } finally {
            if (c != null) holder.unlockCanvasAndPost(c);
        }


    }

    void drawParallax(Canvas c) {
        int frameWidth = mFrame.width();

        for (int i=layers.size()-1; i>=0; i--) {
            Layer layer = layers.get(i);
            Bitmap bitmap = layer.bitmap;
            float bitmapWidth = bitmap.getWidth() * layer.scale;
            float max = frameWidth - bitmapWidth;
            float offset = mOffset * max;

            final Matrix m = layer.getMatrix(offset, 0);

            c.drawBitmap(bitmap, m, null);
        }


    }
4

0 回答 0