title: Android Custom ListView Using Image from URL
body: <p>I've been trying to get my ListView to populate with images from a website URL that is known by the adapter. The activity inflates each image, but my emulator won't even start, and just displays black. I've searched fruitlessly throughout my code, and have tried many things, but unfortunately, I am now stuck.
  First class is my Adapter Class which provides a View for every index
  Second class is my Activity Class which loads the views. Third class is a helper class.</p>
  
  <p>There are also two layout XML files and an XML manifest</p>
  
  <p><strong>GalleryAdapter.java</strong></p>
  
  <pre><code>import java.io.IOException;
  import java.io.InputStream;
  import java.net.HttpURLConnection;
  import java.net.MalformedURLException;
  import java.net.URL;
  
  import com.example.imageshow.R;
  
  import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.os.AsyncTask;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ArrayAdapter;
  import android.widget.ImageView;
  import android.widget.TextView;
  
  
  public class GalleryAdapter extends ArrayAdapter&lt;JSONObject&gt;{
      DrawableManager dM = new DrawableManager();
      Server s = new Server();
      Context ctx;
      LayoutInflater myInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  
      public GalleryAdapter(Context context, int resource) {
          super(context, resource);
          ctx = context;
          // TODO Auto-generated constructor stub
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          // TODO Auto-generated method stub
          if (convertView==null){
              convertView = myInflater.inflate(R.layout.gallery_item, parent, true);
          }
          TextView name = (TextView) convertView.findViewById(R.id.name);
          name.setText(s.galleryObjects.get(position).getName());
          TextView eventDate = (TextView) convertView.findViewById(R.id.eventDate);
          eventDate.setText(s.galleryObjects.get(position).getEventDate());
          ImageView image = (ImageView) convertView.findViewById(R.id.image);
          String imageUrl = s.galleryObjects.get(position).getImageURL();
  
          //which one works??
          //1
          image.setImageDrawable(dM.fetchDrawable(imageUrl));
          //2
          try {
                image = (ImageView) convertView.findViewById(R.id.image);
                Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
                image.setImageBitmap(bitmap); 
              } catch (MalformedURLException e) {
                e.printStackTrace();
              } catch (IOException e) {
                e.printStackTrace();
              }
          //3
          //new DownloadImageTask(image).execute(s.galleryObjects.get(position).getImageURL());
          return convertView;
      }
  
  
  
      public static Bitmap getBitmapFromURL(String src) {
          try {
              Log.e("src",src);
              URL url = new URL(src);
              HttpURLConnection connection = (HttpURLConnection) url.openConnection();
              connection.setDoInput(true);
              connection.connect();
              InputStream input = connection.getInputStream();
              Bitmap myBitmap = BitmapFactory.decodeStream(input);
              Log.e("Bitmap","returned");
              return myBitmap;
          } catch (IOException e) {
              e.printStackTrace();
              Log.e("Exception",e.getMessage());
              return null;
          }
      }
  
      class DownloadImageTask extends AsyncTask&lt;String, Void, Bitmap&gt; {
          ImageView bmImage;
  
          public DownloadImageTask(ImageView bmImage) {
              this.bmImage = bmImage;
          }
  
          protected Bitmap doInBackground(String... urls) {
              String urldisplay = urls[0];
              Bitmap mIcon11 = null;
              try {
                  InputStream in = new java.net.URL(urldisplay).openStream();
                  mIcon11 = BitmapFactory.decodeStream(in);
              } catch (Exception e) {
                  Log.e("Error", e.getMessage());
                  e.printStackTrace();
              }
              return mIcon11;
          }
  
          protected void onPostExecute(Bitmap result) {
              bmImage.setImageBitmap(result);
          }
      }
  
  }
  </code></pre>
  
  <p><strong>GalleryActivity.java</strong></p>
  
  <pre><code>import com.example.imageshow.R;
  import android.app.Activity;
  import android.os.Bundle;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.ImageView;
  import android.widget.ListView;
  
  public class GalleryActivity extends Activity{
  
      @Override
      protected void onCreate(Bundle savedInstanceState){
          super.onCreate(savedInstanceState);
          GalleryAdapter p = new GalleryAdapter(this,0);
          setContentView(R.layout.galleries);
          ListView l = (ListView) findViewById(R.id.galleryList);
          ImageView moreButton = (ImageView) findViewById(R.id.moreButton);
          ImageView cameraButton = (ImageView) findViewById(R.id.cameraButton);
          moreButton.setOnClickListener(new MoreButtonListener());
          cameraButton.setOnClickListener(new CameraButtonListener());
          l.setAdapter(p);
          setVisible(true);
      }
  
      public class MoreButtonListener implements OnClickListener{
  
          @Override
          public void onClick(View v) {
              // TODO Auto-generated method stub
  
          }
  
      }
  
      public class CameraButtonListener implements OnClickListener{
  
          @Override
          public void onClick(View v) {
              // TODO Auto-generated method stub
  
          }
  
      }
  }
  </code></pre>
  
  <p><strong>DrawableManager.Java</strong></p>
  
  <pre><code>import java.io.IOException;
  import java.io.InputStream;
  import java.net.MalformedURLException;
  import java.util.HashMap;
  import java.util.Map;
  
  import org.apache.http.HttpResponse;
  import org.apache.http.client.methods.HttpGet;
  import org.apache.http.impl.client.DefaultHttpClient;
  
  import android.graphics.drawable.Drawable;
  import android.os.Handler;
  import android.os.Message;
  import android.util.Log;
  import android.widget.ImageView;
  
  public class DrawableManager {
      private final Map&lt;String, Drawable&gt; drawableMap;
  
      public DrawableManager() {
          drawableMap = new HashMap&lt;String, Drawable&gt;();
      }
  
      public Drawable fetchDrawable(String urlString) {
          if (drawableMap.containsKey(urlString)) {
              return drawableMap.get(urlString);
          }
  
          try {
              InputStream is = fetch(urlString);
              Drawable drawable = Drawable.createFromStream(is, "src");
  
  
              if (drawable != null) {
                  drawableMap.put(urlString, drawable);
                  Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                          + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                          + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
              } else {
                Log.w(this.getClass().getSimpleName(), "could not get thumbnail");
              }
  
              return drawable;
          } catch (MalformedURLException e) {
              Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
              return null;
          } catch (IOException e) {
              Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
              return null;
          }
      }
  
      public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
          if (drawableMap.containsKey(urlString)) {
              imageView.setImageDrawable(drawableMap.get(urlString));
          }
  
          final Handler handler = new Handler() {
              @Override
              public void handleMessage(Message message) {
                  imageView.setImageDrawable((Drawable) message.obj);
              }
          };
  
          Thread thread = new Thread() {
              @Override
              public void run() {
                  //TODO : set imageView to a "pending" image
                  Drawable drawable = fetchDrawable(urlString);
                  Message message = handler.obtainMessage(1, drawable);
                  handler.sendMessage(message);
              }
          };
          thread.start();
      }
  
      private InputStream fetch(String urlString) throws MalformedURLException, IOException {
          DefaultHttpClient httpClient = new DefaultHttpClient();
          HttpGet request = new HttpGet(urlString);
          HttpResponse response = httpClient.execute(request);
          return response.getEntity().getContent();
      }
  }
  </code></pre>
  
  <p><strong>Layout file</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical" &gt;
  
      &lt;LinearLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:orientation="vertical" &gt;
  
          &lt;RelativeLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="#fbfbfb" &gt;
              &lt;ImageView
                  android:id = "@+id/cameraButton"
                  android:layout_height="wrap_content"
                  android:layout_width = "wrap_content"
                  android:layout_alignParentLeft="true"
                  android:layout_centerVertical="true"
                  android:clickable = "true"
                  android:adjustViewBounds="true"
                  android:padding="10dp"
                  android:maxHeight="400dp"
                  android:src="@drawable/ic_launcher"
                  android:background="#b9b9b9"&gt;
              &lt;/ImageView&gt;
              &lt;TextView
                  android:id="@+id/textView1"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_centerHorizontal="true"
                  android:layout_centerVertical="true"
                  android:clickable="false"
                  android:maxHeight="400dp"
                  android:text="SPORTSPHOTOS.com"
                  android:textColor="#123123" &gt;
              &lt;/TextView&gt;
              &lt;ImageView
                  android:id = "@+id/moreButton"
                  android:layout_height="wrap_content"
                  android:layout_width = "wrap_content"
                  android:layout_alignParentRight="true"
                  android:adjustViewBounds="true"
                  android:clickable="true"
                  android:padding="10dp"
                  android:maxHeight="60dp"
                  android:layout_centerVertical="true"
                  android:src="@drawable/more"
                  &gt;
              &lt;/ImageView&gt;
          &lt;/RelativeLayout&gt;
          &lt;ScrollView
              android:layout_width = "fill_parent"
              android:layout_height="fill_parent"&gt;
  
              &lt;ListView
                  android:id="@+id/galleryList"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content" &gt;
              &lt;/ListView&gt;
  
          &lt;/ScrollView&gt;
  
  
      &lt;/LinearLayout&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p><strong>Layout file</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent" &gt;
  
      &lt;LinearLayout
          android:layout_width = "match_parent"
          android:layout_height = "wrap_content"
          android:padding="20dp"
          android:orientation="vertical"
      &gt;
  
      &lt;TextView
          android:id="@+id/name"
          android:text="Great Wall"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:padding="2dp"&gt;
      &lt;/TextView&gt;
  
      &lt;TextView
          android:id="@+id/eventDate"
          android:text="08-15-2014"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:padding="2dp"&gt;
  
      &lt;/TextView&gt;
  
      &lt;LinearLayout 
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:orientation="vertical"
          android:padding="10dp"&gt;
  
          &lt;ImageView
              android:id="@+id/image"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:adjustViewBounds="true"
              android:maxHeight="200dp"
              android:padding="10dp"&gt;  
          &lt;/ImageView&gt;
  
      &lt;/LinearLayout&gt;
  
      &lt;/LinearLayout&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p><strong>AndroidManifest.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.imageshow"
      android:versionCode="1"
      android:versionName="1.0" &gt;
  
      &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
  
      &lt;uses-sdk
          android:minSdkVersion="18"
          android:targetSdkVersion="21" /&gt;
  
      &lt;application
          android:allowBackup="true"
          android:icon="@drawable/ic_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme" &gt;
          &lt;activity
              android:name=".MainActivity"
              android:label="@string/app_name" &gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.SECOND" /&gt;
  
                  &lt;category android:name="android.intent.category.DEFAULT" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
          &lt;activity
              android:name=".GalleryActivity"
              android:label="@string/app_name" &gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN" /&gt;
  
                  &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
      &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>