kostenloser Webspace werbefrei: lima-city


Android: Bild per URL einfügen

lima-cityForumProgrammiersprachenJava

  1. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    Hallo zusammen,

    ich möchte ein Bild anhand einer URL in meiner App anzeigen lassen. Dafür habe ich folgenden Code gefunden:


    private ImageView image = (ImageView) findViewById(R.id.image);


    public void starteSpiel(){
    	String bildurl = "http://upload.wikimedia.org/wikipedia/commons/e/ee/Crested_Tern_Tasmania_(edit).jpg"; // Zum Test ein Random Bild von Wikipedia
    	bildLaden(bildurl);
    }


    private void bildLaden(String urlString) {
    	URL url = null;
    	try {
    		url = new URL(urlString);
    	} catch (MalformedURLException e) {
    		e.printStackTrace();
    	}
    	Object content = null;
    	try {
    		content = url.getContent();
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    	InputStream is = (InputStream)content;
    	image.setImageDrawable(Drawable.createFromStream(is,"src"));
    }


    Mit dem Code kommt dann folgende Fehlermeldung:

    E/AndroidRuntime(1352): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.example.app/de.example.app.SpielActivity}: android.os.NetworkOnMainThreadException


    Ich habe mich darüber informiert. Anscheinend darf man den Code nicht im UI Thread ausführen, sondern mit einer AsyncTask Klasse. Also habe ich den Code aus der bildLaden Funktion in eine eigene AsyncTask Klasse gepackt, die innerhalb der Activity Klasse ist:

    public class LoadImageTask extends AsyncTask<String, Void, String> {
    
    	@Override
    	protected String doInBackground(String... urls) {
    
    		String result = "";
    		URL url = null;
    		try {
    			url = new URL(urls[0]);
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		}
    		Object content = null;
    		try {
    			content = url.getContent();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		InputStream is = (InputStream)content;
    		image.setImageDrawable(Drawable.createFromStream(is,"src"));
    		return result;
    	}
    }


    Und so wird sie aufgerufen:

    LoadImageTask asyncTask = new LoadImageTask();
    asyncTask.execute(new String[] { bildurl });


    Dann bekomme ich aber folgende Meldung:

    E/AndroidRuntime(2269): java.lang.RuntimeException: An error occured while executing doInBackground()


    Darüber habe ich mich auch informiert, das liegt vermutlich daran, dass man in der doinbackground Methode auf keine Element aus dem UI Thread zugreifen darf, was in diesem Fall das image ist. Ich habe jetzt aber keine Idee mehr, wie ich mein Vorhaben passend umsetzen könnte. Und im Internet finde ich auch nichts passendes mehr. Also ich würde mich sehr über Hilfe freuen.

    Viele Grüße
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. https://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute%28Result%29

    Die Docs zu lesen hilft meistens ;) Eine Möglichkeit wäre einfach das Image als Result zurückzugeben und dann in der oben verlinkten Methode zu setzen.

    Beitrag zuletzt geändert: 16.5.2015 18:03:53 von davidlw
  4. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    davidlw schrieb:
    https://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute%28Result%29

    Die Docs zu lesen hilft meistens ;) Eine Möglichkeit wäre einfach das Image als Result zurückzugeben und dann in der oben verlinkten Methode zu setzen.


    Das hast du Recht, das wäre hilfreich gewesen :) Also ich habs jetzt so umgesetzt:

    public class LoadImageTask extends AsyncTask<String, Void, InputStream> {
    
    	@Override
    	protected InputStream doInBackground(String... urls) {
    
    		URL url = null;
    		try {
    			url = new URL(urls[0]);
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		}
    		Object content = null;
    		try {
    			content = url.getContent();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		InputStream is = (InputStream)content;
    		return is;
    	}
    		
    	@Override
    	protected void onPostExecute(InputStream result) {
    		image.setImageDrawable(Drawable.createFromStream(result,"src"));
    	}
    }


    Jetzt kommt zumindest schonmal keine Fehlermeldung mehr, allerdings wird mir auch kein Bild angezeigt. Die Stelle bleibt einfach Weiß. Weiß jemand was jetzt noch falsch ist?

    EDIT:

    Das steht im LogCat:


    D/skia(2606): ---- read threw an exception
    D/skia(2606): --- SkImageDecoder::Factory returned null




    Beitrag zuletzt geändert: 16.5.2015 18:51:06 von ultimate-bravery
  5. Ich würde an deiner stelle das Image/Drawable schon in der doInBackground Methode erstellen. Ich weiß nicht genau, wie das von Android/Java gehandhabt wird, aber es kann gut sein, dass du so erst in der postExecute Methode anfängst Daten vom Server zu lesen, die Verbindung aber schon wieder geschlossen wurde.
    Generell finde ich den Aufbau so aber auch logischer, denn so ist klar getrennt zwischen Image vom Server laden und in das Bild dann anzeigen.

    Beitrag zuletzt geändert: 16.5.2015 19:15:44 von davidlw
  6. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    Ich habe jetzt eine funktionierende Lösung gefunden:

    public class LoadImageTask extends AsyncTask<String, Void, Bitmap> {
    
    	@Override
    	protected Bitmap doInBackground(String... params) {
            // TODO Auto-generated method stub
            String urlStr = params[0];
            Bitmap img = null;
    
            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet(urlStr);
            HttpResponse response;
            try {
                response = (HttpResponse)client.execute(request);           
                HttpEntity entity = response.getEntity();
                BufferedHttpEntity bufferedEntity = new BufferedHttpEntity(entity);
                InputStream inputStream = bufferedEntity.getContent();
                img = BitmapFactory.decodeStream(inputStream);
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return img;
        }
    	
    	@Override
    	protected void onPostExecute(Bitmap result) {
    		image.setImageBitmap(result);
    	}
    }
  7. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!