Android Gallery Probleme

Dagobert

Bekanntes Mitglied
Guten Morgen,
Nun habe ich endlich wieder Zeit mich ein bisschen mit Android zu beschäftigen. Jedoch bekomme ich einfach keinen klaren Draht dazu in meinem Fall.
Ich habe eine anzahl von hochauflösenden Fotos (imo 10). Diese liegen (bis jetzt) im Ordner "res/raw/"
Jetzt möchte ich diese einfach in irgend einer Form darstellen.
Ich habe mich erstmal dazu entschlossen die ListActivity zu benutzen.
Dann habe ich mir einen eigenen kleinen ImageAdapter geschrieben, jedoch bekomme ich dort beim Ausführen immer einen
Code:
android signal 11
Fehler, welcher auf ein gravierendes Problem bei meinem ImageAdapter hinweist. Jedoch weis ich nicht wie es richtig mache. oO
Ich hab auch schon die ersten Seiten bei Google durch, ohne wirklich neue Hinweise bekommen zu haben.
Hier ist mal mein ImageAdapter:
Java:
package de.muehlensoft.hornpaper;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter {

	private Context mContext;
	private int[] id = { R.raw.horn1, R.raw.horn2, R.raw.horn3, R.raw.horn4,
//			R.raw.horn5, R.raw.horn6, R.raw.horn7, R.raw.horn8, R.raw.horn9,
//			R.raw.horn10 
			};

	public ImageAdapter(Context context) {
		this.mContext = context;
	}

	public int getCount() {
		return id.length;
	}

	public Object getItem(int position) {
		return id[position];
	}

	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		ImageView imageView = null;
		if (convertView == null) {
			imageView = new ImageView(mContext);
			imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
			imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
			imageView.setPadding(8, 8, 8, 8);
		} else {
			imageView = (ImageView) convertView;
		}
		Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), id[position]);
		imageView.setImageBitmap(bitmap);

		return imageView;
	}
}

mfg. Dagobert
 
Hallo Dagobert,

- warum legst du die Bilder nicht in /res/drawable ?
- es muss Gallery.LayoutParams heißen, nicht GridLayout.LayoutParams (jede View hat ihre eigenen LayoutParams als eigene innere Klasse)
- statt
Java:
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), id[position]);
        imageView.setImageBitmap(bitmap);
kannst auch einfach
Java:
imageView.setImageResource(id[position]);
schreiben

Nun aber zum eigentlichen Fehler:
"android signal 11" bedeutet denke ich OutOfMemoryError.
Du musst die Bilder also runter-skalieren.
Android ist hat nunmal weniger RAM, CPU, Bildschirmauflösung, Plattenplatz, Übertragungsrate, ect.

Hoffe das hilft dir,

javaDev2011
 
warum legst du die Bilder nicht in /res/drawable ?
Weil ich es später noch in der vollen Auflösung brauche.
es muss Gallery.LayoutParams heißen, nicht GridLayout.LayoutParams (jede View hat ihre eigenen LayoutParams als eigene innere Klasse)
Das hab ich auch schon bemerkt... danke aber für den hinweis...
mein aktueller Stand sieht jetzt so aus:
Java:
package de.muehlensoft.hornpaper.view;

import java.util.WeakHashMap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import de.muehlensoft.hornpaper.R;

public class ImageAdapter extends BaseAdapter {

	private static final String TAG = "ImageAdapter";
	private WeakHashMap<Integer, Bitmap> cache;
	
	private Context mContext;
	private int[] id = { R.raw.horn1, R.raw.horn2, /*R.raw.horn3, R.raw.horn4,
			R.raw.horn5, R.raw.horn6, R.raw.horn7, R.raw.horn8, R.raw.horn9,
			R.raw.horn10*/ };

	public ImageAdapter(Context context) {
		this.mContext = context;
		cache = new WeakHashMap<Integer, Bitmap>();
	}

	public int getCount() {
		return id.length;
	}

	public Object getItem(int position) {
		return id[position];
	}

	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		ImageView imageView = null;
		int id = this.id[position];
		if (convertView == null) {
			imageView = new ImageView(mContext);
			imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
			imageView.setPadding(5, 5, 5, 5);
			
		} else {
			imageView = (ImageView) convertView;
		}
		
		if(cache.containsKey(id)) {
			imageView.setImageBitmap(cache.get(id));
		} else {
			Log.d(TAG, "scale image " + id);
			Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), id);
			bitmap = Bitmap.createScaledBitmap(bitmap, 150, 150, true);
			cache.put(id, bitmap);
			imageView.setImageBitmap(bitmap);
		}
		
		return imageView;
	}
}
Leider bekomme ich so auch nicht mal 10 Bilder geladen =/ Iwas muss ich doch noch falsch machen^^

mfg. Dagobert
 
Alles in allem ist das sowieso eine sehr unschöne Lösung, weil du dir so die Möglichkeit zerschießt, den Speicher vom System managen zu lassen.

So musst du bei jedem Bild die teuren Bitmap-Operationen ausführen lassen.

Du könntest zumindest das erste Bitmap, also das in der vollen Größe, recyclen wenn du es nicht mehr brauchst.

Java:
Bitmap fullRes = // code
Bitmap showPic = // Bitmap scale code
fullRes.recylce();

Ich persönlich würde es eher so machen, dass du die Bilder vorher skalierst und beide Bilder in deiner App mitgibst. Damit verlagerst du den Aufwand des Skalieren auf deinen Build-Prozess anstatt den Benutzer zu zwingen jedes Mal wenn er sich die Bilder anschauen möchte die Bilder zu skalieren.

Wenn es umbedingt auf dem Gerät passieren muss, solltest du die skalierten Bilder zumindest auf der SD-Karte cachen.
 

Zurück
Oben