2

For my custom list view, I'm using AsyncTask for the web service call and it is working fine. My List view have a left side image, title, descriptions. the service will return a list of (url, title, desc).

And in my adapter, i'm loading the images using the following code:

httpClient = new DefaultHttpClient(); 
HttpGet request = new HttpGet(url);         
response = httpClient.execute(request);
InputStream is = response.getEntity().getContent();
Drawable drawable = Drawable.createFromStream(is, "src");
imgView.setImageDrawable(drawable);

But I'm not able to see the list view until all the images loaded, I know i'm blocking the UI thread, can anybody suggest the best way to do this without UI blocking.

Thanks, Venkat Papana

Venkat Papana
  • 4,757
  • 13
  • 52
  • 74
  • The concept you need to implement is known as "ListView - Image Lazy Loading" and here is the best example i have ever found: http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012 , just check this. – Paresh Mayani Sep 24 '11 at 09:56

4 Answers4

3

Use an AsyncTask or a Thread with a Handler like the above answers have noted.

Here is a quick way to get an image resource from a URL:

BitmapDrawable bitmapDrawable = new BitmapDrawable(BitmapFactory.decodeStream(new URL("http://example.com/path/to/image/file.jpg").openStream()));

Create 1 AsyncTask, and in the doInBackground, loop through all your image URLS and add each resulting drawable to an icon list, or something

james
  • 26,141
  • 19
  • 95
  • 113
2
new Thread(new Runnable() {

                           @Override
                           public void run() {

                                       httpClient = new DefaultHttpClient(); 
                                       HttpGet request = new HttpGet(url);         
                                       response = httpClient.execute(request);
                                       InputStream is =  response.getEntity().getContent();
                                     msg.obj=is;
                                   mHandler.sendMessage(msg);
                           }
                   }).start();

and your handle will be like this

mHandler = new Handler() { 
              @Override public void handleMessage(Message msg) { 
                 InputStream is=(InputStream)msg.obj;
                 Drawable drawable = Drawable.createFromStream(is, "src");
                 imgView.setImageDrawable(drawable);

              }
          };
Sunil Pandey
  • 7,042
  • 7
  • 35
  • 48
  • 1
    Thank you Sunil, I need to create this new Thread in side an array adapter of a list activity, so i need to create number of threads as per the list elements, in that case how can I know which message is related to specific thread..? – Venkat Papana Mar 17 '11 at 15:47
1

This is the better way just try.. this is for image load in cardview

private class LoadImage extends AsyncTask<String, String, Bitmap> {
    Bitmap bitmap1 = null;
    CurrentVehicleStatus currentVehicleStatus;

    int i;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //Stuff on preexecute

        pDialog = new ProgressDialog(AdminActivity.this);
        pDialog.setTitle("Please wait");
        pDialog.setMessage("Loading data..");
        pDialog.show();

    }
    protected Bitmap doInBackground(String... args) {

           for(int i=0;i<arrayLength;i++) {
          //Your class reference that store your values for adapter
          yourClassReference = yourArrayList.get(i);

            try {
                bitmap = BitmapFactory.decodeStream((InputStream) new URL("Your URL"
                ).getContent());

            } catch (Exception e) {
                e.printStackTrace();
            }
    //this setImage method in data class
      yourArrayList.get(i).setImage(bitmap);

         }

        }


        return bitmap1;
    }

    protected void onPostExecute(Bitmap image) {

        pDialog.dismiss();
    //Notify adapter
        mAdapter.notifyDataSetChanged();

    }
}

is there any doubt comment me

Muhammed Fasil
  • 7,909
  • 2
  • 19
  • 28
1

Use an AsyncTask for image loading as well. For each loaded image, you can call publishResults() from the doInBackground() and then have onProgressUpdate() put the image in the right place.

Heiko Rupp
  • 30,426
  • 13
  • 82
  • 119
  • Thank you Heiko, but when i gone through AsyncTask documentation, they mentioned we can call AsyncTask's execute only once; but in my requirement, i need to call AsyncTask for a number of times. how can i? – Venkat Papana Mar 17 '11 at 15:44
  • Use a new AsyncTask each time for (int i = 0 ; i < 10 ; i++ ) { new MyAsyncTask().execute(i); } – Heiko Rupp Mar 17 '11 at 16:39
  • Hi Heiko, how do we identify the perticular AsyncTask inside onPostExecute() method, for eg, if (new MyAsyncTaks()).execute(5) finished execution first, then how to update the 5th list item's image view? – Venkat Papana Mar 18 '11 at 06:34
  • You can pass the respective image view in the constructor of the AsyncTask ( new MyAsyncTask(iv).execute() ) -- or when you want to handle multiple images, pass a list of IV in the constructor and then iterate over them inside the AsyncTask's doInBackground – Heiko Rupp Apr 24 '11 at 07:00