java.lang.OutOfMemoryError(surfaceview类)

时间:2015-01-03 21:13:19

标签: java android bitmap surfaceview

我有一个扩展了surfaceview的类,在几次app崩溃后,我开始了另一个活动。

这是我的LogCat:

01-02 21:37:16.332: E/AndroidRuntime(28449): FATAL EXCEPTION: main
01-02 21:37:16.332: E/AndroidRuntime(28449): java.lang.OutOfMemoryError
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:596)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:472)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:502)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at com.DainiusSal.simplegame.Zaisti.<init>(Zaisti.java:39)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at com.DainiusSal.simplegame.Leidejas.onCreate(Leidejas.java:24)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.app.Activity.performCreate(Activity.java:5372)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.app.ActivityThread.access$700(ActivityThread.java:159)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.os.Looper.loop(Looper.java:176)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at android.app.ActivityThread.main(ActivityThread.java:5419)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at java.lang.reflect.Method.invokeNative(Native Method)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at java.lang.reflect.Method.invoke(Method.java:525)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
01-02 21:37:16.332: E/AndroidRuntime(28449):    at dalvik.system.NativeStart.main(Native Method) 

我的代码来自Zaisti.java类:

public class Zaisti extends SurfaceView implements Runnable{

Bitmap kamuolys = BitmapFactory.decodeResource(getResources(), R.drawable.green);
Bitmap  kliutis = BitmapFactory.decodeResource(getResources(), R.drawable.purple);
Bitmap bg = BitmapFactory.decodeResource(getResources(), R.drawable.background);

public Zaisti(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        laikytojas = getHolder();

    }

public void pause() {
        veikia = false;

        if(mThread!=null){
            try {
                mThread.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        mThread = null;
    }

    public void resume() {  
        score = 0;
        veikia = true;
        mThread = new Thread(this);
        mThread.start();

    }

    public void run() {
        // TODO Auto-generated method stub

        bg = Bitmap.createScaledBitmap(bg, width, height, false);
        kamuolys = Bitmap.createScaledBitmap(kamuolys,(int) (kamuolys.getWidth()/1.5),(int) (kamuolys.getHeight()/1.5), false);

    while (veikia) {
            if (!laikytojas.getSurface().isValid()) {
                continue;
            }


            Canvas drobe = laikytojas.lockCanvas();

            //background
            drobe.drawBitmap(bg, 0, 0, null);

            drobe.drawBitmap(kamuolys, 50, yk, null);


            drobe.drawBitmap(kliutis, kliuties, virsus, null);
            drobe.drawBitmap(kliutis, kliuties1, virsus1, null);
            drobe.drawBitmap(kliutis, kliuties2, virsus2, null);
            drobe.drawBitmap(kliutis, kliuties3, virsus3, null);

        if (yk > (virsus + kamuolys.getHeight()) || (yk + kamuolys.getHeight()) < virsus) {

            } else {
                if (50 > (kliuties + kamuolys.getWidth()) || (50 + kamuolys.getWidth()) < kliuties) {

                } else {
                    veikia = false;
                }
            }

            if (yk > (virsus1 + kamuolys.getHeight()) || (yk + kamuolys.getHeight()) < virsus1) {

            } else {
                if (50 > (kliuties1 + kamuolys.getWidth()) || (50 + kamuolys.getWidth()) < kliuties1) {

                } else {
                    veikia = false;
                }
            }

            if (yk > (virsus2 + kamuolys.getHeight()) || (yk + kamuolys.getHeight()) < virsus2) {

            } else {
                if (50 > (kliuties2 + kamuolys.getWidth()) || (50 + kamuolys.getWidth()) < kliuties2) {

                } else {
                    veikia = false;
                }
            }

            if (yk > (virsus3 + kamuolys.getHeight()) || (yk + kamuolys.getHeight()) < virsus3) {

            } else {
                if (50 > (kliuties3 + kamuolys.getWidth()) || (50 + kamuolys.getWidth()) < kliuties3) {

                } else {
                    veikia = false;
                }
            }

           laikytojas.unlockCanvasAndPost(drobe);


        }

    Intent intent = new Intent().setClass(getContext(), Pabaiga.class);
    getContext().startActivity(intent);
    ((Activity) getContext()).finish();
}

来自Leidejas.java的代码:

public class Leidejas extends Activity implements OnTouchListener{

    Zaisti vaizdas;
    float y=0,y1=0;
    int musicid = 0;
    SoundPool sp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);


        vaizdas = new Zaisti(this);
        vaizdas.setOnTouchListener(this);
        setContentView(vaizdas);

        //load music
        sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
        musicid = sp.load(this, R.raw.kulka, 1);

    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();    
        vaizdas.pause();
    }


    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        vaizdas.resume();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub

        switch(event.getAction()){

        case MotionEvent.ACTION_DOWN:
            y = event.getY();
            break;
        case MotionEvent.ACTION_UP:
            y1 = event.getY();

        if(y<y1){
            //zemyn
        while(vaizdas.yk < ((vaizdas.height/2)+1))  {

        vaizdas.yk += 0.0005;
        }

        //play sound
        if(musicid!=0)
        sp.play(musicid, 1, 1, 0, 0, 1);

        }else if(y>y1){
            //aukstyn
            while(vaizdas.yk > ((vaizdas.height/2)-(vaizdas.kamuolys.getHeight()))) {   

                vaizdas.yk -= 0.0005;
                }

            //play sound
            if(musicid!=0)
            sp.play(musicid, 1, 1, 0, 0, 1);

        }
        break; 
        }



        return true;
    }


}

请帮我解决崩溃问题!

1 个答案:

答案 0 :(得分:0)

考虑将BitmapFactory.decodeResource()替换为Bitmap.createScaledBitmap()

如果您将多个大图片加载到内存中,您将体验OutOfMemoryException,这似乎是您的问题。使用Bitmap.createScaledBitmap()可能会减少应用的内存占用量。