I am using android listview with lazyadapter to show images and textview in list.
and when user scrolls to the bottom i am using AsyncTask to add more contents but when i execute AsyncTask it kills the process.
here is my code.
mainactivity
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.NodeList;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.sax.Element;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class AndroidJSONParsingActivity extends Activity {
// url to make request
// JSON Node names
static final String TAG_CONTACTS = "comics";
static final String TAG_ID = "id";
static final String TAG_NAME = "title";
static final String TAG_EMAIL = "id";
static final String TAG_PHONE_MOBILE = "image";
// contacts JSONArray
JSONArray contacts = null;
ListView list;
LazyAdapter adapter;
static int counter = 0;
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list=(ListView)findViewById(R.id.list);
// call the function
LoadData();
}
public void LoadData(){
String url = "http://myurl?start=" + counter;
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
contacts = json.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
for(int i = 0; i < contacts.length(); i++){
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
String mobile = "http://www.funnydash.com/uploads/s/" + c.getString(TAG_PHONE_MOBILE);
// Phone number is agin JSON Object
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_EMAIL, email);
map.put(TAG_PHONE_MOBILE, mobile);
// adding HashList to ArrayList
contactList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
/**
* Updating parsed JSON data into ListView
* */
// Getting adapter by passing xml data ArrayList
adapter=new LazyAdapter(this, contactList);
list.setAdapter(adapter);
list.setOnScrollListener(new EndlessScrollListener());
}
public class BackgroundLoadMore extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
}
protected Void doInBackground(Void... unused) {
LoadData();
return (null);
}
protected void onPostExecute(Void unused) {
// On completing background task
// closing progress dialog etc,.
list.setOnScrollListener(new EndlessScrollListener());
}
}
public class EndlessScrollListener implements OnScrollListener {
private int visibleThreshold = 0;
private int currentPage = 0;
private int previousTotal = 0;
private boolean loading = true;
public EndlessScrollListener() {
}
public EndlessScrollListener(int visibleThreshold) {
this.visibleThreshold = visibleThreshold;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
counter +=12;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// I load the next page of gigs using a background task,
// but you can call any function here.
new BackgroundLoadMore().execute();
loading = true;
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
}
}
Lazyadapter.java
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
TextView title = (TextView)vi.findViewById(R.id.title); // title
TextView artist = (TextView)vi.findViewById(R.id.artist); // artist name
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // thumb image
HashMap<String, String> song = new HashMap<String, String>();
song = data.get(position);
// Setting all values in listview
title.setText(song.get(AndroidJSONParsingActivity.TAG_NAME));
artist.setText(song.get(AndroidJSONParsingActivity.TAG_ID));
imageLoader.DisplayImage(song.get(AndroidJSONParsingActivity.TAG_PHONE_MOBILE), thumb_image);
return vi;
}
}
and this is what i get in my logcat
The problem is because you’re attempting to set an adapter on your list from outside the UI thread. Views in Android can not be modified in a background thread, which in this case, means you can not modify the UI from the
doInBackgroundmethod of anAsyncTask. So, your methodLoadData()can’t call the following:You will need to return some data (probably
contactList) from yourdoInBackground()method, and then move the offending code to theonPostExecute()method, which is run on the UI thread.The key problem noted in the stack trace is: