1

I hava an app that load images from the internet and display using the combination of gallery widget and imageview. I would like to put the downloading images part to a separate thread but i had no idea how to do it even after a few google searches. Below is my code, anyone can please help me. Thanks in advance.

package com.example.gallery;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;

public class GalleryActivity extends Activity {
public Bitmap[] bmps;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Gallery gal = (Gallery)findViewById(R.id.gallery);

    final ImageView iv = (ImageView)findViewById(R.id.imageView);

    gal.setAdapter(new ImageAdapter(this));

    gal.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent,
            View v, int position, long id) {        

            Bitmap bm = bmps[position];
            if(bm.getHeight() > 800 || bm.getWidth() > 600) 
            {
                Bitmap rbm = Bitmap.createScaledBitmap(bm, bm.getWidth()/2, bm.getHeight()/2, true);
                iv.setImageBitmap(rbm);
            }
            else
            {
                iv.setImageBitmap(bm);
            }

        }
    });
}

public void initBmps(int length)
{
    bmps = new Bitmap[length];
}

public void setBmps(Bitmap bm, int pos)
{
    bmps[pos] = bm;
}

public class ImageAdapter extends BaseAdapter
{
    int mGalleryItemBackground;
    private Context mContext;

    private String[] mImageIds = {"http://4.bp.blogspot.com/-bQQ6UcJhpoA/TfOeymYKMeI/AAAAAAAAAIo/30kj0KUAgxo/s1600/snsd1.jpg",
                                    "http://www.sweetslyrics.com/images/img_gal/13192_snsd-group-31.jpg", 
                                    "http://kojaproductions.files.wordpress.com/2008/12/snsd_teases_kjp.jpg",
                                    "http://solar.envirohub.net/images/solar-power.jpg",
                                    "http://scm-l3.technorati.com/11/05/27/35419/solar-power.jpg?t=20110527104336",
                                    "http://www.solarstorms.org/Pictures/GridMap.gif",
                                    "http://static.electro-tech-online.com/imgcache/11039-power%20lines.jpg"};


    public ImageAdapter(Context c) 
    {
        mContext = c;
        TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme);
        mGalleryItemBackground = a.getResourceId(R.styleable.Theme_android_galleryItemBackground, 0);
        initBmps(mImageIds.length);
        a.recycle();
    }

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

    public Object getItem(int position)
    {
        return position;
    }

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

    public View getView(int position, View convertView, ViewGroup parent)
    {
        ImageView i = new ImageView(mContext);

            DownloadImageTask down = new DownloadImageTask();
            down.excecute(mImageIds[position]);

            if(down..getStatus() == AsyncTask.Status.FINISHED)
            {

              Bitmap rbm = Bitmap.createScaledBitmap(bm, 200, 200, true);

              i.setImageBitmap(rbm);
              i.setLayoutParams(new Gallery.LayoutParams(150, 150));
              i.setScaleType(ImageView.ScaleType.FIT_XY);
              i.setBackgroundResource(mGalleryItemBackground);
            }
            return i;
    }

 private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(String... url) {
            // TODO Auto-generated method stub
            Toast.makeText(getApplicationContext(), url[0], Toast.LENGTH_SHORT).show();
            URL aURL;
            Bitmap bm = null;
            try {
                aURL = new URL(url[0]);
                URLConnection conn = aURL.openConnection();
                conn.connect();
                InputStream is = conn.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                bm = BitmapFactory.decodeStream(bis);
                //setBmps(bm, position);
                bis.close();
                is.close();
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return null;
        }

        protected void onPostExecute (Bitmap result) {
            setBm(result);
        }

    }

}
}
chenhou90
  • 23
  • 7
  • I had added the AsyncTask to my code, but my app will just suddenly died off. And the error is always the same. Anyone know why? Does it have anything to with the code after calling the AsyncTask? – chenhou90 Sep 25 '11 at 17:41
  • Looks like you started the debugger more than once? I don't see where you started your DownloadImageTask, am I missing it? – Alan Moore Sep 25 '11 at 18:22
  • I had restarted the android VM and the error is gone. I had modified my code to perform certain task after the AsyncTask is finish but it seems that it does not goes into the if statement. Could the problem be that i am calling the AsyncTask more then once? – chenhou90 Sep 26 '11 at 00:40

3 Answers3

0

I suggest you use an AsyncTask to do your image download, that's what I've been using:

http://developer.android.com/reference/android/os/AsyncTask.html

http://developer.android.com/resources/articles/painless-threading.html

Alan Moore
  • 6,525
  • 6
  • 55
  • 68
0

Well, googling 'Android threading', this seems to be an article on pretty much what you're trying to do:

http://developer.android.com/resources/articles/painless-threading.html

In general:

http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html

The API:

http://developer.android.com/reference/java/lang/Thread.html

Ivo
  • 5,378
  • 2
  • 18
  • 18
0

Ok

Here are some ImageDownloader references.

They delegate the image downloading to an AsyncTask

Reno
  • 33,594
  • 11
  • 89
  • 102