Images in Java-Code einbinden

K

Knoxxx

Fortgeschrittenes Mitglied
0
Hallo,

ich habe mehrere activities mit Bildern. Momentan sind die Bilder (aus dem drawable-Ordner) nur im XML-Code definiert. Da die App hin und wieder abstürzt durch einen OutOfMemory-Error, muss ich die Bilder auch in den Java-Code einbinden. Kennt jmd von euch den Code dafür?

VG
Knoxxx
 
Du kannst die Binärdaten natürlich als byte[] im Java Code ablegen und via BitmapFactory.decodeByteArray() daraus dein Bild bauen, aber ich möchte wetten, dass du weiterhin OutOfMemoryErros bekommen wirst, weil der Fehler im Umgang mit Bildern meist ganz wo anders liegt.
 
Ich glaube schon, dass der OutOfMemory-Error durch zu große Bilder entsteht. Denn wenn ich die Bilder auf 20KB verkleinere, dann bekomme ich keinen OutOfMemory-Fehler mehr. Nur sind die Bilder dann unscharf. Was meinst du?
 
Paar Infos: Displaying Bitmaps Efficiently | Android Developers

Darüber hinaus wären mehr Infos sinnig. Bspw. um was für eine App es sich handelt, was für Bilder, wie oft die Bilder verwendet werden sollen etc, sodass andere sich ein Bild machen können. Deine Aussage "hin und wieder stürzt die App ab" ist hier eher wenig hilfreich.

Nichtsdestotrotz scheint mir einfach ein memory leak Problem in deiner App zu existieren. Vermutlich, weil du die Bilder ggf. nicht recyclest.
 
Ok. Die App ist ein Fotoalbum. Sie besteht aus 70 activities und in jeder activitiy ist ein jpeg oder png- Bild zu sehen. Und zwei Pfeile, um zur nächsten oder vorherigen Seite zu gelangen. Die Bilder nehmen ca. 1/3 des Layouts ein. Sie sind im drawable-Ordner gespeichert und sind nicht im Java-Code definiert. Es ist nichts besonderes und ich weiß, dass man auch anders ein Fotoalbum kreieren kann. Momentan möchte ich es aber so machen wie beschrieben. Die App stürzt jedes Mal nach dem ich sie ausprobiere nach einiger Zeit ab. D.h. ich schaffe es immer ca. 50 activities zu öffnen und dann stoppt die App. Sie stoppt nicht immer an der gleichen Stelle. Manchmal schaffe ich es 47 activities zu öffnen. Ein anderes mal 52 activities. Wenn sie abstürzt steht im LogCat "OutOfMemory-Error". Wenn ich die Bilder aber jeweils auf ca. 20KB verkleinere, dann läuft die App immer einwandfrei. Doch die Bilder sind dann unscharf. Wenn ich die Bilder dann jeweils auf ca. 100KB vergrößere, dann sind sie zwar scharf, aber die App stürzt wie gesagt nach ca. 50 activites ab und zeigt einen "Out-Of-Memory-Error" an. Daher glaube ich, dass die Bilder mit 100KB zu groß sind und ich sie in meinen Java-Code einbinden muss. Damit nicht so viele Ressourcen verbraucht werden.
 
Ob du Bilder in "Java" einbindest oder sonstwie ist relativ egal, sehe das wie DieGoldeneMitte -> denn auch Bilder die aus Java-Code entstehen werden zu Bitmaps umgerechnet.

Für mich - ich wiederhole mich - ganz klares Problem eines Memory Leaks! Punkt! Recycle deine Bilder, wenn die Activities beendet werden und du wirst das Problem nicht mehr haben.

Irgendwas in die Richtung:

PHP:
if (bitmap != null) {
    bitmap.recycle();
    bitmap = null;
}
 
wow also bei 70 activities ist ja klar dass du out of memory gehst:lol::thumbsup:

wenn di activity verlassen wird speichert er wohl deine bilder im Bundle savedInstancestate ab

nun rechne dir mal aus bei 50 bilder zu je 100kb sind das schon 5 mb an bildern im speciher und dir stehen von seitens android nur eine bestimmt heap size an speicher zur verfügung
 
Zuletzt bearbeitet:
@Jaiel: Na die Anzahl der Activities hat ja erstmal garnichts zu sagen. Aber das steht ja auch nicht zur Frage, ob seine App oder die Umsetzung sinnvoll ist.

Zum Thema 50 Bilder x 100kb = 5mb. Sollte höher sein als 5mb. Glaube nicht, dass er Bilder direkt als bmp hinterlegt, sondern als png - also einem komprimierten Format. Dies wird bei Benutzung aber afaik in Bitmap umgerechnet, verbraucht also deutlich mehr.
 
Ok, dann versuch ich das mal mit dem recyclen. Vielen Dank! Aber bei dem von dir genannten Link steht auch was von "Loading large Images efficiently". Damit kein OutOfMemory-Error entsteht. Und da steht nichts von recyclen?!
 
Habe extra den Link des obersten Beitrags gepostet "Displaying Bitmaps Efficiently". Dort ist das Loading ja nur ein Unterpunkt.

Schau mal bei https://developer.android.com/training/displaying-bitmaps/manage-memory.html
Dort steht unter 2.3.3 and lower das recycle-Gedöhns und für neuere andere Methoden. Wobei recyclen natürlich auch bei neueren Android-Versionen funktioniert.
 
@reneph ja hab ich auch nciht behauptet es sit ja wohl die emnge an daten die jede activity mit sich bringt

es würde eine activity mit einer bitmap die recycled wird wohl auch reichen
 
So sieht mein Code aus. Das müsste so passen. Und jetzt muss ich den recycle() Code hinzufügen, damit kein OutOfMemoryError mehr erscheint, oder? Aber reicht es nicht die activity einfach zu beenden mit finish(); ?

Code:
 public class Picture1 extends Activity {

            public ImageView iv; @Override
            protected void onCreate(Bundle savedInstanceState) {
                // TODO Auto-generated method stub
                super.onCreate(savedInstanceState);
                setContentView(R.layout.pic1);

               iv = (ImageView)findViewById(R.id.imageView1);}

               public void Menue (View view){
            Intent i = new Intent(this, MainActivity.class);             
            startActivity(i);}

               public void Pic0 (View view){
            Intent i = new Intent(this, Picture0.class);             
            startActivity(i);}

               public void Pic2 (View view){
            Intent i = new Intent(this, Picture2.class);             
            startActivity(i);}}
Code:
 <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

         <ImageView
            android:id="@+id/imageView1"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_centerInParent="true"
            android:layout_marginLeft="14dp"
            android:src="@drawable/picture1" />

        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:src="@drawable/arrowright" 
            android:onClick="Pic2"/>

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:layout_alignTop="@+id/imageView3"
            android:layout_centerHorizontal="true"
            android:onClick="Menue"
            android:src="@drawable/Menue" />

        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:src="@drawable/arrowleft" 
            android:onClick="Pic0"/>
 
Zuletzt bearbeitet:
Im Prinzip müsste finish() reichen, aber es muss auch (richtig) aufgerufen werden. Dein Code sieht nicht danach aus. Ich sehe nur Haufen von startActivity() die einen Monster-backstack erzeugen.
 
Ja momentan habe ich kein finish drin. Ich hatte es mal so, aber das hatte auch nicht geholfen. Oder mache ich was falsch?
Code:
 public void Menue (View view){
            Intent i = new Intent(this, MainActivity.class);             
            startActivity(i);
            finish();}

               public void Pic0 (View view){
            Intent i = new Intent(this, Picture0.class);             
            startActivity(i);
            finish();

}

               public void Pic2 (View view){
            Intent i = new Intent(this, Picture2.class);             
            startActivity(i);
            finish(); }}
 
Problem hat sich erledigt. Habe finish(); im Code beibehalten, aber musste zusätzlich folgenden Code ins Manifest schreiben:
Code:
android:hardwareAccelerated="false"
android:largeHeap="true"
 
Zuletzt bearbeitet:
Sorry, aber DAS ist keine wirkliche Lösung.

Das ist nur - sorry - ein dreckiger Workaround, der auch wieder an seine Grenzen stoßen wird. Memory Leaks sollte man richtig lösen, anstatt sowas. Aber naja okay, ist deine Sache... ;)

android:largeHeap schrieb:
Most apps should not need this and should instead focus on reducing their overall memory usage for improved performance. Enabling this also does not guarantee a fixed increase in available memory, because some devices are constrained by their total available memory.
 
ok, habe es weggelassen und es funktioniert trotzdem. Habe wohl irgendwo ein finish() zu wenig gehabt als ich das das erste Mal ausprobiert habe. Bei 70 activities hatte ich wohl was übersehen. Sorry und vielen Dank!
 
Merkst selber das du deine Architektur mal überarbeiten solltest...
 

Ähnliche Themen

D
Antworten
23
Aufrufe
2.542
Data2006
D
S
Antworten
9
Aufrufe
1.208
swa00
swa00
B
Antworten
7
Aufrufe
1.346
bqde
B
Zurück
Oben Unten