Thursday, July 8, 2010

Load ListView in background AsyncTask

Refer to the old exercise "ListView with icon loaded from internet", it's a time-consume task to load bitmap from internet. So the code is modified in this exercise, a AsyncTask is implemented to handle the ListView: the bitmap is loaded in background thread, and setListAdapter() in onPostExecute().

Load ListView in background AsyncTask

row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"/>
<TextView
android:id="@+id/weekofday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>


AndroidList.java

package com.exercise.AndroidList;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.ListActivity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidList extends ListActivity {

public class backgroundLoadListView extends
  AsyncTask<Void, Void, Void> {

 @Override
 protected void onPostExecute(Void result) {
  // TODO Auto-generated method stub
  setListAdapter(new MyCustomAdapter(AndroidList.this, R.layout.row, month));
  Toast.makeText(AndroidList.this,
    "onPostExecute \n: setListAdapter after bitmap preloaded",
    Toast.LENGTH_LONG).show();
 }

 @Override
 protected void onPreExecute() {
  // TODO Auto-generated method stub
  Toast.makeText(AndroidList.this,
    "onPreExecute \n: preload bitmap in AsyncTask",
    Toast.LENGTH_LONG).show();
 }

 @Override
 protected Void doInBackground(Void... params) {
  // TODO Auto-generated method stub
  preLoadSrcBitmap();
  return null;
 }

}

String image_URL=
 "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcEgpwOmfwpIOR0xnLXhb_-_jo3xworzj_yFYAPA3WbxMMSg6aVJ65aTZ-laab3WOsgEfsi1eN8FJ-l0lmZi7s-rben-6NPl3jQJrzuykfcFfy31JScNMpKUYfA9sgxB4cf0whQOqjP4nD/s1600-r/android.png";

public class MyCustomAdapter extends ArrayAdapter<String> {
 Bitmap bm;

 public MyCustomAdapter(Context context, int textViewResourceId,
   String[] objects) {
  super(context, textViewResourceId, objects);
  // TODO Auto-generated constructor stub
 
  bm = srcBitmap;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  // TODO Auto-generated method stub
  //return super.getView(position, convertView, parent);
 
  View row = convertView;
 
  if(row==null){
   LayoutInflater inflater=getLayoutInflater();
   row=inflater.inflate(R.layout.row, parent, false);
  }
 
  TextView label=(TextView)row.findViewById(R.id.weekofday);
  label.setText(month[position]);
  ImageView icon=(ImageView)row.findViewById(R.id.icon);
 
  icon.setImageBitmap(bm);
 
  return row;
 }
}

Bitmap srcBitmap;
private void preLoadSrcBitmap(){
 BitmapFactory.Options bmOptions;
 bmOptions = new BitmapFactory.Options();
 bmOptions.inSampleSize = 1;
 srcBitmap = LoadImage(image_URL, bmOptions);
}

String[] month = {
  "January", "February", "March", "April",
  "May", "June", "July", "August",
  "September", "October", "November", "December"
  };

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 //setContentView(R.layout.main);

 /*setListAdapter(new ArrayAdapter<String>(this,
       R.layout.row, R.id.weekofday, DayOfWeek));*/
 new backgroundLoadListView().execute();
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
 // TODO Auto-generated method stub
 //super.onListItemClick(l, v, position, id);
 String selection = l.getItemAtPosition(position).toString();
 Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}

private Bitmap LoadImage(String URL, BitmapFactory.Options options)
{     
 Bitmap bitmap = null;
 InputStream in = null;     
 try {
  in = OpenHttpConnection(URL);
  bitmap = BitmapFactory.decodeStream(in, null, options);
  in.close();
 } catch (IOException e1) {
 }

 return bitmap;               
}

private InputStream OpenHttpConnection(String strURL) throws IOException{
 InputStream inputStream = null;
 URL url = new URL(strURL);
 URLConnection conn = url.openConnection();

 try{
  HttpURLConnection httpConn = (HttpURLConnection)conn;
  httpConn.setRequestMethod("GET");
  httpConn.connect();
 
  if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
   inputStream = httpConn.getInputStream(); 
  } 
 }
 catch (Exception ex){
 }

 return inputStream;
}
}

please note that in order to permit the App to access to internet, we have to grand it permission of "android.permission.INTERNET"; refer to the last exercise "Load ImageView with bitmap from internet"


Download the files.

Related:
Async load image from internet to ListView

13 comments:

Unknown said...

Its really worth mentioning that you need to add the "Uses Permission" "Internet" to the AndroidManifest.xml in order to get this code to work...

Erik said...

Thx Robert, the notice about Permission is added.

Unknown said...

You share files using a site that has multiple viruses, exploits, and trojans when you try to download from there.
Don't be a horses ass - remove it jerk.

Erik said...

hello homer,

Thx for your advise. I want to use other service also, some of my old files lost.

Any suggest? please let me know.

Erik said...

Dear Android Ashish,

I have no idea to do so!

Unknown said...

Thank you, i was setting asyntask outside main class and get static reference issue (setListAdapter), must have a child from main, now works. :))

Unknown said...

What if i have a list of links to get the image and post it in the listview...
what to do if i use a for loop for all links and get image and set it in the listview.

for loop here
String image_URL;
image_URL= "http://someapi/adminpanel/logo/"+aa ;

Erik said...

hello Hari Sankar,

Please read Async load image from internet to ListView.

Unknown said...

Hi, I'm Anh, I come from VietNamese..
I have a problem about playlist in mediaplay...You can help me about list view playlist??
Help me..I feel it so difficult...
Thank you so much...

Erik said...

hello Ánh Kiều,

I'm not sure.
You can try to post here.

Unknown said...

Thank you very much...
It is:
When I open Android Device Monitor and it say:
Monitor:
An error occurred. See the log file:
C:\Android\sdk\tools\lib\monitor-x86_64\configuration\1449081260203.log.
I want to create a list songs but I don't know how to work ..
It was my project..
And I want to load list songs in sdcard but I didn't cop data to my
computer from sdcard.. I opened Android Device Monitor and had a
problem..It was...Thank so much..

Unknown said...

I want to create a list songs but I don't know how to work ..
It was my project..
And I want to load list songs in sdcard but I didn't cop data to my
computer from sdcard.. I opened Android Device Monitor and had a
problem..It was...Thank so much..
Thank you very much...
> It is:
> When I open Android Device Monitor and it say:
> Monitor:
> An error occurred. See the log file:
> C:\Android\sdk\tools\lib\monitor-x86_64\configuration\1449081260203.log.

Erik said...

Hello Ánh Kiều,

Sorry, I have no idea for your problem!