Java Referenzen von Bildobjekten löschen

muss ich dann auch onCreate durch onStart ersetzen?
 
Zuletzt bearbeitet:
was heißt ersetzen.. du solltest deine Bilder statt in der onCreate in der onStart Methode laden. Wurde aber alles schon geschrieben ;)
 
Code:
package com.example.www.test;

import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.appindexing.Thing;
import com.google.android.gms.common.api.GoogleApiClient;

public class Jubel extends AppCompatActivity {
    public Spinner spinner1;
    public String[] spinnertext = {"Laufbewegungen", "Abschlussbewegungen (1/2)", "Abschlussbewegungen (2/2)", "EAS FC - Freischaltbare Objekte"};
    public ImageView imageView12;
    public ImageView imageView8;
    public ImageView imageView16;
    public ImageView imageView17;
    public ImageView imageView18;
    public ImageView imageView20;
    public ImageView imageView21;
    public ImageView imageView15;
    public ImageView imageView13;
    public ImageView imageView22;
    public ImageView imageView19;
    public ImageView imageView23;
    public ImageView imageView24;
    public ImageView imageView25;
    public ImageView imageView26;
    public ImageView imageView27;
    public ImageView imageView29;
    public ImageView imageView28;
    public ImageView imageView30;
    public ImageView imageView31;


    

    @Override
    protected void onStart(){
        super.onStart();

        setContentView(R.layout.activity_jubel);
        imageView12 = (ImageView) findViewById(R.id.imageView12);
        imageView12.setImageResource(R.drawable.thumbsuck2);
        imageView8 = (ImageView) findViewById(R.id.imageView8);
        imageView8.setImageResource(R.drawable.onearmraised1);
        imageView16 = (ImageView) findViewById(R.id.imageView16);
        imageView16.setImageResource(R.drawable.wristflick6);
        imageView17 = (ImageView) findViewById(R.id.imageView17);
        imageView17.setImageResource(R.drawable.aeroplane7);
        imageView18 = (ImageView) findViewById(R.id.imageView18);
        imageView18.setImageResource(R.drawable.pointtosky8);
        imageView20 = (ImageView) findViewById(R.id.imageView20);
        imageView20.setImageResource(R.drawable.canyouhearme11);
        imageView21 = (ImageView) findViewById(R.id.imageView21);
        imageView21.setImageResource(R.drawable.handsout12);
        imageView15 = (ImageView) findViewById(R.id.imageView15);
        imageView15.setImageResource(R.drawable.armsout5);
        imageView13 = (ImageView) findViewById(R.id.imageView13);
        imageView13.setImageResource(R.drawable.eartwist3);
        imageView22 = (ImageView) findViewById(R.id.imageView22);
        imageView22.setImageResource(R.drawable.fingerpoint4);
        imageView19 = (ImageView) findViewById(R.id.imageView19);
        imageView19.setImageResource(R.drawable.telephone10);
        imageView23 = (ImageView) findViewById(R.id.imageView23);
        imageView23.setImageResource(R.drawable.shhhhh9);
        imageView24 = (ImageView) findViewById(R.id.imageView24);
        imageView24.setImageResource(R.drawable.comeon13);
        imageView25 = (ImageView) findViewById(R.id.imageView25);
        imageView25.setImageResource(R.drawable.doublearmswing15);
        imageView26 = (ImageView) findViewById(R.id.imageView26);
        imageView26.setImageResource(R.drawable.flyingbird16);
        imageView27 = (ImageView) findViewById(R.id.imageView27);
        imageView27.setImageResource(R.drawable.handonhead17);
        imageView29 = (ImageView) findViewById(R.id.imageView29);
        imageView29.setImageResource(R.drawable.armspointingup19);
        imageView28 = (ImageView) findViewById(R.id.imageView28);
        imageView28.setImageResource(R.drawable.heartsymbol18);
        imageView30 = (ImageView) findViewById(R.id.imageView30);
        imageView30.setImageResource(R.drawable.windmill20);
        imageView31 = (ImageView) findViewById(R.id.imageView31);
        imageView31.setImageResource(R.drawable.blowkisses14);


        spinner1 = (Spinner) findViewById(R.id.spinner1);


        ArrayAdapter<String> spinneradapter = new ArrayAdapter<String>(Jubel.this, android.R.layout.simple_spinner_dropdown_item, spinnertext);
       spinner1.setAdapter(spinneradapter);
        spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {


            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                int spinnerposition = spinner1.getSelectedItemPosition();

                switch (spinnerposition) {

                    case 0: {
                        break;
                    }

                    case 1: {

                        Intent intent = new Intent(Jubel.this,JubelAbschluss.class);
                        startActivity(intent);

                        break;
                    }

                    case 2: {

                        Intent intent = new Intent(Jubel.this,JubelAbschluss2.class);
                        startActivity(intent);

                        break;
                    }

                    case 3: {

                        Intent intent = new Intent(Jubel.this,JubelEAS.class);
                        startActivity(intent);

                        break;

                    }
                }
            }
                    @Override
                    public void onNothingSelected (AdapterView < ? > parent){

                    }
                } );}

    public void ToHome(View view) {


        Intent intent = new Intent(this,MainActivity.class);
        startActivity(intent);
    }

    @Override
    public void onStop() {
      super.onStop();
        ((BitmapDrawable)imageView12.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView8.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView16.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView17.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView18.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView20.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView21.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView15.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView13.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView22.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView19.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView23.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView24.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView25.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView26.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView27.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView28.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView29.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView30.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView31.getDrawable()).getBitmap().recycle();

    }
}

Immer noch dasselbe Problem :/
 
Es sollten nur die Bildzuweisungen nach onStart, nicht das komplette onCeate. Lies dir nochmal durch, was diese Methoden machen! Ohne Grundlagen geht es nicht.
Das finish() solltest du nicht weglassen. Mir erscheint das sinvoll, aber ich kenne ja den Programmablauf nicht. Evtl. wären hier sogar Fragmente sinnvoller, aber das würde zu weit führen.

Nutzt du Android Studio? Dann starte den Android Monitor und guck wie sich der Speicherverbrauch beim wechseln der Aktivitäten verhält.

Ich muss auch mal ganz dumm nachfragen: Die anderen Aktivitäten hast du genau so geändert?
 
Ja, habe die anderen Activities auch geändert. Habe mir auch mal den Verlauf des Speichers angesehen: Mit jeder geöffneten Activity geht der Speicher noch höher... :(

Code:
package com.example.www.test;

import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.appindexing.Thing;
import com.google.android.gms.common.api.GoogleApiClient;

public class Jubel extends AppCompatActivity {
    public Spinner spinner1;
    public String[] spinnertext = {"Laufbewegungen", "Abschlussbewegungen (1/2)", "Abschlussbewegungen (2/2)", "EAS FC - Freischaltbare Objekte"};
    public ImageView imageView12;
    public ImageView imageView8;
    public ImageView imageView16;
    public ImageView imageView17;
    public ImageView imageView18;
    public ImageView imageView20;
    public ImageView imageView21;
    public ImageView imageView15;
    public ImageView imageView13;
    public ImageView imageView22;
    public ImageView imageView19;
    public ImageView imageView23;
    public ImageView imageView24;
    public ImageView imageView25;
    public ImageView imageView26;
    public ImageView imageView27;
    public ImageView imageView29;
    public ImageView imageView28;
    public ImageView imageView30;
    public ImageView imageView31;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jubel);

        spinner1 = (Spinner) findViewById(R.id.spinner1);
        ArrayAdapter<String> spinneradapter = new ArrayAdapter<String>(Jubel.this, android.R.layout.simple_spinner_dropdown_item, spinnertext);
        spinner1.setAdapter(spinneradapter);
        spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                int spinnerposition = spinner1.getSelectedItemPosition();

                switch (spinnerposition) {

                    case 0: {
                        break;
                    }

                    case 1: {
                        finish();
                        Intent intent = new Intent(Jubel.this,JubelAbschluss.class);
                        startActivity(intent);

                        break;
                    }

                    case 2: {
                        finish();
                        Intent intent = new Intent(Jubel.this,JubelAbschluss2.class);
                        startActivity(intent);

                        break;
                    }

                    case 3: {
                        finish();
                        Intent intent = new Intent(Jubel.this,JubelEAS.class);
                        startActivity(intent);

                        break;

                    }
                }
            }
                    @Override
                    public void onNothingSelected (AdapterView < ? > parent){

                    }
                } );}

    @Override
    protected void onStart(){
    super.onStart();
        imageView12 = (ImageView) findViewById(R.id.imageView12);
        imageView12.setImageResource(R.drawable.thumbsuck2);
        imageView8 = (ImageView) findViewById(R.id.imageView8);
        imageView8.setImageResource(R.drawable.onearmraised1);
        imageView16 = (ImageView) findViewById(R.id.imageView16);
        imageView16.setImageResource(R.drawable.wristflick6);
        imageView17 = (ImageView) findViewById(R.id.imageView17);
        imageView17.setImageResource(R.drawable.aeroplane7);
        imageView18 = (ImageView) findViewById(R.id.imageView18);
        imageView18.setImageResource(R.drawable.pointtosky8);
        imageView20 = (ImageView) findViewById(R.id.imageView20);
        imageView20.setImageResource(R.drawable.canyouhearme11);
        imageView21 = (ImageView) findViewById(R.id.imageView21);
        imageView21.setImageResource(R.drawable.handsout12);
        imageView15 = (ImageView) findViewById(R.id.imageView15);
        imageView15.setImageResource(R.drawable.armsout5);
        imageView13 = (ImageView) findViewById(R.id.imageView13);
        imageView13.setImageResource(R.drawable.eartwist3);
        imageView22 = (ImageView) findViewById(R.id.imageView22);
        imageView22.setImageResource(R.drawable.fingerpoint4);
        imageView19 = (ImageView) findViewById(R.id.imageView19);
        imageView19.setImageResource(R.drawable.telephone10);
        imageView23 = (ImageView) findViewById(R.id.imageView23);
        imageView23.setImageResource(R.drawable.shhhhh9);
        imageView24 = (ImageView) findViewById(R.id.imageView24);
        imageView24.setImageResource(R.drawable.comeon13);
        imageView25 = (ImageView) findViewById(R.id.imageView25);
        imageView25.setImageResource(R.drawable.doublearmswing15);
        imageView26 = (ImageView) findViewById(R.id.imageView26);
        imageView26.setImageResource(R.drawable.flyingbird16);
        imageView27 = (ImageView) findViewById(R.id.imageView27);
        imageView27.setImageResource(R.drawable.handonhead17);
        imageView29 = (ImageView) findViewById(R.id.imageView29);
        imageView29.setImageResource(R.drawable.armspointingup19);
        imageView28 = (ImageView) findViewById(R.id.imageView28);
        imageView28.setImageResource(R.drawable.heartsymbol18);
        imageView30 = (ImageView) findViewById(R.id.imageView30);
        imageView30.setImageResource(R.drawable.windmill20);
        imageView31 = (ImageView) findViewById(R.id.imageView31);
        imageView31.setImageResource(R.drawable.blowkisses14);
    }

    public void ToHome(View view) {
        Intent intent = new Intent(this,MainActivity.class);
        startActivity(intent);
        finish();
    }

    @Override
    public void onStop() {
      super.onStop();
       ((BitmapDrawable)imageView12.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView8.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView16.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView17.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView18.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView20.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView21.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView15.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView13.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView22.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView19.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView23.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView24.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView25.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView26.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView27.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView28.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView29.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView30.getDrawable()).getBitmap().recycle();
        ((BitmapDrawable)imageView31.getDrawable()).getBitmap().recycle();

    }
}

So langsam verzweifle ich...
 
Normalerweise sollte der Speicherverbrauch wieder runtergehen, wenn Speicher angefordert wird (die Anzeige sollte wie eine Achterbahn aussehen). Wie verhällt sich die Anzeige, wenn du auf den Homescreen gehst und dann die App über den App-Verlauf wieder aufrufst?

Ruf zusätzlich zum recycle noch setDrawable(null) auf, das löscht die Referenz aus der ImageView und setz das super.onStop() an das Ende.

Design-Tip: Felder, auf die nicht von außen zugegriffen werden soll, sollten auf private gesetzt werden.
 
Wenn ich auf den Homescreen gehe, verändert sich der Speicher nicht. Möchte ich dann die App wieder aufrufen, hält sie an. Deine weiteren Vorschläge habe ich auch umgesetzt, allerdings ohne Erfolg :(
 
Dann musst du jetzt die Bilder runterrechnen um Speicher zu sparen.
 
Nein, nicht unbedingt. Wenn du nur 2-3 Bilder in der Aktivität hättest vielleicht, aber bei der Menge muss man sich genauer mit der Materie beschäftigen. Du entwickelst hier für ein Smartphone (glaube ich?) und nicht für einen PC.
 
Edit: Drücke ich auf den Home Button, geht der Speicher der App nach ein paar Sekunden runter auf 18 MB! Kann es also sein, dass ich programmiert habe, dass die Bilder nur aus dem Speicher geworfen werden, wenn die komplette App gestoppt wird und nicht beim Schließen der einzelnen Activities?
 
Die App wird nicht gestoppt, sondern die aktuelle Aktivität, dort hast ja in onStop die Bilder freigegeben.
Der Speicher wird auch nicht immer sofort freigegeben, meist erst wenn mehr Speicher benötigt wird.
 
Aber warum wird der Speicher erst freigegeben, wenn ich aus der App rausgehe (indem ich z.B. den Homebutton drücke) und nicht, wenn ich eine Activity öffne und gleichzeitig eine mit finish() schließe?

forumspeicher.PNG

Bsp.: Nach 25 Sekunden öffne ich die erste Activity mit Bildern, der benutzte Speicher springt auf 60 MB. Nach ca. 35 Sekunden öffne ich die nächste Activity. Normalerweise sollte der Speicher erst hochgehen, weil die weiteren Bilder geladen werden, und dann runtergehen, weil die aus der vorherigen Activity nun eigentlich aus dem Speicher geworfen werden sollten (oder?). Nach ca. 50 Sekunden drücke ich dann den Homebutton meines Smartphones; erst jetzt werden die Bilder aus dem Speicher gelöscht, aber das soll ja geschehen, wenn ich eine Activity mithilfe des Spinners öffne und somit die vorige geschlossen wird. Ich kann ja nicht jedes mal den Homebutton drücken und erst dann wieder in die App gehen, damit ich sie benutzen kann.
 
So funktioniert aber nunmal die Speicherverwaltung von Android, da hast du nicht direkt Einfluss drauf. Speicher freigeben ist "teuer", daher wird das bei aktiven Apps nur dann gemacht, wenn es nötig ist.

Und nochmal: 60MB sind viel zu viel, damit wird deine App nicht auf allen Smartphones laufen können.
 
Resize doch deine Bilder oder konvertiere die in ein weniger speicherfressendes Format. Das kannste auch außerhalb der App machen oder In-App. Das wurde Dir aber auch schon gesagt.
 
habe jetzt von png zu jpg geändert. Speicher pro bild also von knapp 200 kb auf 40 kb reduziert. in der speicheranzeige wird aber immer noch angezeigt, dass ich genauso viel Speicher belege wie davor, als die bilder noch im png format waren (s.o.). Wo ist da die Logik?
 
Das Dateiformat spielt keine Rolle. Wenn das Bild 1000x1000 Pixel hat, belegt es immer x MB im Speicher, egal welches Format dahinter steckt.
 
Zurück
Oben