ListView like Android Market Application with separator and ColdFusion as web server


Hi folks. This time I’m presenting a huge post.

This post will cover following things:

  • ListView with separator
  • Pagination  like Android Market application

I know that not all of you knows ColdFusion and its component (cfc), but it is just a server part like your web service code.

myWebservice.cfc

<cfcomponent displayname="myWebservice">
	<cffunction name="getJobs" access="remote" output="false" returntype="struct">
		<cfargument name="currentPage" required="true" type="numeric" default='1' />
		<cfargument name="totalRecord" required="true" type="numeric" default="10" />
		<cfargument name="searchString" required="false" type="string" default="" />
		<cfset var qResult = "">
		<cfset var condition = "" />
		<cfset var startRow = (arguments.CurrentPage-1) * arguments.TotalRecord +1 />
		<cfset var endRow = startRow + arguments.TotalRecord -1 />
		<cfset var qGetAllRecord = "" />
		<cfset var gridStruct = "" />
		<cfif len(arguments.searchString)>
			<cfset condition = condition & " -- your search conditions goes here" />
		</cfif>
		<cfstoredproc procedure="usp_Pagination" datasource="#application.DSN#" username="#application.DBUID#" password="#application.DBPWD#">
			<cfprocresult name="qGetAllRecord" resultset="1">
			<cfprocresult name="qtotalRecord" resultset="2">
			<cfprocparam dbvarname="@SqlColumns" cfsqltype="CF_SQL_VARCHAR" value="*">
			<cfprocparam dbvarname="@SqlFriendlyColumns" cfsqltype="CF_SQL_VARCHAR" value="*">
			<cfprocparam dbvarname="@SqlTableClause" cfsqltype="CF_SQL_VARCHAR" value="Jobs">
			<cfprocparam dbvarname="@StartRow" cfsqltype="CF_SQL_VARCHAR" value="#startRow#">
			<cfprocparam dbvarname="@EndRow" cfsqltype="CF_SQL_VARCHAR" value="#endRow#">
			<cfprocparam dbvarname="@SqlWhere" cfsqltype="CF_SQL_VARCHAR" value="#condition#">
			<cfprocparam dbvarname="@SqlRowNumOrderBy" cfsqltype="CF_SQL_VARCHAR" value="Jobs.createdDate desc">
			<cfprocparam dbvarname="@SqlOuterOrderBy" cfsqltype="CF_SQL_VARCHAR" value="createdDate desc">
		</cfstoredproc>
		<cfset gridStruct=StructNew() />
		<cfset gridStruct.query = qGetAllRecord />
		<cfset gridStruct.totalRowCount=qtotalRecord.countAll />
		<cfreturn qResult>
	</cffunction>
</cfcomponent>

The reason behind showing this code is to let you know the implementation of the server part.

In above function, I am returning fix number of records from my database. It is used to pull out ten ten records from a query that has thousands of records.

Now I’m calling this web service like:

http://localhost/cfc/mywebservice.cfc?returnformat=json&method=getJobs&currentPage=5&totalRecord=10

And it returns a data in JSON format like:

{“QUERY”:{“COLUMNS”:[“JOBID”,”JOBTITLE”,”CREATEDATE”,”JOBDETAIL”],”DATA”:[[“1″,”Title1″,”January, 25 2011 10:55:53″,”Detail is here”],[“2″,”Title2″,”January, 25 2011 10:55:53″,”Detail is here”],[“3″,”Title3″,”January, 20 2011 14:13:10″,”Detail is here”],[“4″,”Title4″,”January, 20 2011 14:13:10″,”Detail is here”],[“5″,”Title5″,”January, 20 2011 14:13:10″,”Detail is here”],[“6″,”Title6″,”January, 20 2011 14:13:10″,”Detail is here”],[“7″,”Title7″,”January, 18 2011 16:23:28″,”Detail is here”],[“8″,”Title8″,”January, 17 2011 11:22:02″,”Detail is here”],[“9″,”Title9″,”January, 11 2011 09:22:32″,”Detail is here”],[“10″,”Title10″,”January, 11 2011 09:22:32″,”Detail is here”]]},”TOTALROWCOUNT”:”120″}

Now we are ready to build Android app.

joblist.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="fill_parent"
	android:orientation="vertical">
 <EditText android:id="@+id/JobSearch"
 		android:layout_height="wrap_content"
		android:layout_width="fill_parent"
		android:singleLine="true"
 		android:hint="Search"/>
	<ListView android:id="@+id/JobList"
 		android:layout_width="fill_parent"
		android:layout_height="wrap_content" />
	<TextView android:id="@+id/EmptyJobList" android:layout_width="fill_parent"
		android:layout_height="fill_parent" android:text="No Results" android:visibility="invisible" />
</LinearLayout>

joblistheader.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="wrap_content">
	<TextView android:id="@+id/JobDate" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:gravity="center"
		style="?android:attr/listSeparatorTextViewStyle" />
</LinearLayout>

joblistitem.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="wrap_content" android:paddingRight="5px">
	<TextView android:id="@+id/JobTitle" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:layout_alignParentLeft="true"
		android:text="jobTitle" style="?android:attr/textAppearanceLarge" />
	<TextView android:id="@+id/JobDetail"
		android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>

And MyJobListView.java

package com.isummation.listview;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.TreeSet;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MyListView extends Activity {
	private static boolean isInitialized;
	private static int JOBID_IDX;
	private static int JOBTITLE_IDX;
	private static int CREATEDDATE_IDX;
	private static int JOBDETAIL_IDX;
	private JobListAdapter jobListAdapter;
	private long TotalRowCount;
	private int totalRecordPerCall = 20;
	private Date lastDate;
	private EditText JobSearch;
	private ListView list;

	class JobListRowData {
		boolean isHeader;
		Date jobCreationDate;
		int jobId;
		String jobTitle;
		String jobDetail;
	}

	class JobListAdapter extends BaseAdapter {
		private static final int TYPE_ITEM = 0;
		private static final int TYPE_SEPARATOR = 1;
		private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
		private LayoutInflater mInflater;
		private ArrayList mData = new ArrayList();
		private TreeSet mSeparatorsSet = new TreeSet();
		private int count = 0;
		private boolean isCleared = true;

		public JobListAdapter() {
			mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			initialize();
		}

		public void ParseJSONArray(JSONArray JQueryData) {
			int len = JQueryData.length();

			final TextView EmptyListView = (TextView) findViewById(R.id.EmptyJobList);

			if (TotalRowCount == 0) {
				EmptyListView.setVisibility(View.VISIBLE);
			} else {
				EmptyListView.setVisibility(View.INVISIBLE);
			}
			try {
				for (int i = 0; i &lt; len; i++) {

					Date tempDate = new Date(JQueryData.getJSONArray(i)
					.getString(CREATEDDATE_IDX));

					if (lastDate == null) {
						JobListRowData jobListRowData = new JobListRowData();
						jobListRowData.isHeader = true;
						jobListRowData.jobCreationDate = new Date(JQueryData.getJSONArray(i)
								.getString(CREATEDDATE_IDX));
						addSeparatorItem(jobListRowData);

						jobListRowData = new JobListRowData();
						jobListRowData.jobId = JQueryData.getJSONArray(i)
								.getInt(JOBID_IDX);
						jobListRowData.jobTitle = JQueryData.getJSONArray(i)
								.getString(JOBTITLE_IDX);
						jobListRowData.jobDetail = JQueryData.getJSONArray(i)
								.getString(JOBDETAIL_IDX);
						addItem(jobListRowData);

						lastDate = new Date(JQueryData.getJSONArray(i)
								.getString(CREATEDDATE_IDX));
					} else if (lastDate.getDate() == tempDate.getDate()
							&amp;&amp; lastDate.getMonth() == tempDate.getMonth()
							&amp;&amp; lastDate.getYear() == tempDate.getYear()) {
						JobListRowData jobListRowData = new JobListRowData();
						jobListRowData.jobId = JQueryData.getJSONArray(i)
								.getInt(JOBID_IDX);
						jobListRowData.jobTitle = JQueryData.getJSONArray(i)
								.getString(JOBTITLE_IDX);
						jobListRowData.jobDetail = JQueryData.getJSONArray(i)
								.getString(JOBDETAIL_IDX);
						addItem(jobListRowData);
					} else {
						JobListRowData jobListRowData = new JobListRowData();
						jobListRowData.isHeader = true;
						jobListRowData.jobCreationDate = new Date(JQueryData.getJSONArray(i)
								.getString(CREATEDDATE_IDX));
						addSeparatorItem(jobListRowData);
						lastDate = new Date(JQueryData.getJSONArray(i)
								.getString(CREATEDDATE_IDX));

						jobListRowData = new JobListRowData();
						jobListRowData.jobId = JQueryData.getJSONArray(i)
								.getInt(JOBID_IDX);
						jobListRowData.jobTitle = JQueryData.getJSONArray(i)
								.getString(JOBTITLE_IDX);
						jobListRowData.jobDetail = JQueryData.getJSONArray(i)
								.getString(JOBDETAIL_IDX);
						addItem(jobListRowData);
					}

				}
			} catch (Exception e) {
				Toast.makeText(getApplicationContext(), e.getMessage(),
						Toast.LENGTH_LONG).show();
				Log.e(e.getClass().getName(), e.getMessage(), e);
				TotalRowCount = 0;
			}
		}

		public void initialize() {
			isCleared = false;
			count = 0;
			lastDate = null;
			mSeparatorsSet.clear();
			mData.clear();
			JSONArray JQueryData = getJobs(1);
			ParseJSONArray(JQueryData);
			isCleared = true;
		}

		public void addMoreData() {
			if (jobListAdapter.count &lt; TotalRowCount &amp;&amp; isCleared) { 
				JSONArray JQueryData = getJobs((jobListAdapter.count + totalRecordPerCall)
						/ totalRecordPerCall + 1);
				ParseJSONArray(JQueryData);
			}
		}

		public void addItem(final JobListRowData item) {
			mData.add(item);
			count += 1;
			notifyDataSetChanged();
		}

		public void addSeparatorItem(final JobListRowData item) {
			mData.add(item);
			mSeparatorsSet.add(mData.size() - 1);
			notifyDataSetChanged();
		}

		public int getItemViewType(int position) {
			return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR
					: TYPE_ITEM;
		}

		public int getViewTypeCount() {
			return TYPE_MAX_COUNT;
		}

		public int getCount() {
			return mData.size();
		}

		public JobListRowData getItem(int pos) {
			return mData.get(pos);
		}

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

		@Override
		public boolean isEnabled(int position) {
			return mSeparatorsSet.contains(position) ? false : true;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			int type = getItemViewType(position);
			if (convertView == null) {
				holder = new ViewHolder();
				switch (type) {
				case TYPE_ITEM:
					convertView = mInflater.inflate(R.layout.joblistitem, null);
					holder.text = (TextView) convertView
							.findViewById(R.id.JobTitle);
					holder.text2 = (TextView) convertView
							.findViewById(R.id.JobDetail);
					break;
				case TYPE_SEPARATOR:
					convertView = mInflater.inflate(R.layout.joblistheader,
							null);
					holder.text = (TextView) convertView
							.findViewById(R.id.JobDate);
					break;
				}
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}
			switch (type) {
			case TYPE_ITEM:
				holder.text.setText(mData.get(position).jobTitle);
				holder.text2.setText(mData.get(position).jobDetail);
				break;
			case TYPE_SEPARATOR:
				try {
					holder.text
							.setText(android.text.format.DateFormat.format(
									"MMM dd, yyyy",
									mData.get(position).jobCreationDate));
				} catch (Exception e) {
					Toast.makeText(getApplicationContext(), e.getMessage(),
							Toast.LENGTH_LONG).show();
					Log.e(e.getClass().getName(), e.getMessage(), e);
				}
				break;
			}
			return convertView;
		}

		class ViewHolder {
			TextView text;
			TextView text2;
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.joblist);

		JobSearch = (EditText) findViewById(R.id.JobSearch);
		JobSearch.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
		JobSearch.setOnKeyListener(new View.OnKeyListener() {

			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (keyCode == KeyEvent.KEYCODE_ENTER
						&amp;&amp; event.getAction() == KeyEvent.ACTION_DOWN) {
					jobListAdapter.initialize();
				}
				return false;
			}
		});

		jobListAdapter = new JobListAdapter();

		list = (ListView) findViewById(R.id.JobList);
		list.setAdapter(jobListAdapter);
		list.setOnScrollListener(new AbsListView.OnScrollListener() {

			public void onScrollStateChanged(AbsListView view, int scrollState) {

			}

			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				boolean loadMore = firstVisibleItem + visibleItemCount &gt;= totalItemCount;
				if (loadMore) {
					jobListAdapter.addMoreData();
				}
			}
		});

		list.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<!--?--> parent, View view,
					int position, long id) {
				JobListRowData item = jobListAdapter.getItem(position);
				if (!item.isHeader) {
					// start another activity
				}
			}
		});
	}

	public JSONArray getJobs(int currentPage) {
		try {
			String searchString = JobSearch.getText().toString();
			HttpClient httpClient = new DefaultHttpClient();
			HttpContext localContext = new BasicHttpContext();
			HttpGet httpGet = new HttpGet(
					"http://10.0.2.2/cfc/iphonewebservice.cfc?returnformat=json&amp;method=getJobs¤tPage="
							+ URLEncoder.encode("" + currentPage, "UTF-8")
							+ "&amp;totalRecord="
							+ totalRecordPerCall
							+ "&amp;searchString="
							+ URLEncoder.encode(searchString, "UTF-8"));
			HttpResponse response = httpClient.execute(httpGet, localContext);

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					response.getEntity().getContent(), "UTF-8"));
			String sResponse = reader.readLine();
			JSONObject JResponse = new JSONObject(sResponse);
			JSONObject JQuery = JResponse.getJSONObject("QUERY");
			TotalRowCount = JResponse.getLong("TOTALROWCOUNT");
			JSONArray JQueryColumns = JQuery.getJSONArray("COLUMNS");

			if (!isInitialized) {
				int len = JQueryColumns.length();
				for (int i = 0; i &lt; len; i++) {
					if (JQueryColumns.getString(i).equals("JOBID")) {
						JOBID_IDX = i;
					} else if (JQueryColumns.getString(i).equals("JOBTITLE")) {
						JOBTITLE_IDX = i;
					} else if (JQueryColumns.getString(i).equals("CREATEDATE")) {
						CREATEDDATE_IDX = i;
					} else if (JQueryColumns.getString(i).equals(
							"JOBDETAIL")) {
						JOBDETAIL_IDX = i;
					}
				}
				isInitialized = true;
			}

			return JQuery.getJSONArray("DATA");
		} catch (Exception e) {
			Toast.makeText(getApplicationContext(), e.getMessage(),
					Toast.LENGTH_LONG).show();
			Log.e(e.getClass().getName(), e.getMessage(), e);
			finish();
			return new JSONArray();
		}
	}
}

Update:

I’ve updated above code, for “Loading…” effect while getting next 20 records.
You can now download the source code.
Download source code

Advertisements

21 thoughts on “ListView like Android Market Application with separator and ColdFusion as web server

  1. Thanks for your post. It is very good.
    I implemented a listview with some changes and I’m getting an error when I scroll it. If I take the header out, the error doesn’t occur. Do you have an idea to solve that?

    I appreciate your help.
    Leonardo Vannucci

    1. The error would be in getView() function. Make sure that get the instance of each item of the holder, while inflating a view. e.g. check lines: holder.text = (TextView) convertView.findViewById(R.id.JobTitle); In LogCat you may get Nullpointer exception in above case.

  2. This is on of great post in android, i ve searched in stack overflow but i m not getting gud and clear idea like dis
    Thanks for posting and belive in share knowledge

    Happy sharing….:)

  3. I’ve updated the code to display loading effect while showing next 20 records.
    You can now download the source code.
    Hope this post help you….

  4. hi vikas,
    i want to do the same concept but my webservice file will be xml i have to parse that xml and have to render first 20records into listview and then next 20 records so on it should get load..plz can u help me out,this is my first android appn so i’m struggling plz help me…

  5. in my app i have to bring listview as same as the android market app…i’m waiting for ur reply, since my task deadline has finished but i’m still stuggling in this part….

      1. ya i parsed xml and got that data displayed in list view also,but now i can able to show ly 20 record in list view, but i want to load next 20 record so on when i scroll down the list view…so far i parsed a xml which is in single url i don’t how to show list view same as android market app which loads data dynamically when we scroll down…what should i do..can u help with some codes…

  6. the contents of 20 records was in single url, next 20 records will be in another url so on…initially i have to load first 20 records in listview, while scrolling down to 21st record then next 21st to 40 records should get loaded in that listview how to do this, same wise for remaining records also should me done…in webservice xml file they ll give the information totally how many records they are going to send(for eg:total 3000 records) according to that i have to run the loop….i’m using DOM parser and parsed 20 records which get loaded initially and displayed in listview and don’t know how to do the remaining process which i stated above…i’m jst few month old for Development thats why feeling hard for this task, plz help me….

    1. First of all ask your project leader that why do we use XML? I’m not saying that XML is not good but JSON is far better. There are lots of advantages over XML. The Wertheimer first one is “reduce HTTP response size”. There are others too. And I’m sure that converting XML to JSON is not hard at (in server side).
      Study my example from my post. You just need to maintain one counter and one persistent data source. On each call you need to add those 20 records to that data source. Let me know if you get any problem with that. I can provide you help not your job work.

  7. Hello
    Great article I love it, the best (and possibly only) downloadable example of scrolling pagination on Android.
    I have had to modify your code slightly as I am using PHP and Mysql on the back end.

    I am getting a null exception somewhere — here is my log cat if that helps . thanks in advance Ian

    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): java.lang.NullPointerException
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at java.util.Calendar.setTime(Calendar.java:1325)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.text.format.DateFormat.format(DateFormat.java:420)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at com.isummation.listview.MyListView$JobListAdapter.getView(MyListView.java:296)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.AbsListView.obtainView(AbsListView.java:1409)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.ListView.addViewBelow(ListView.java:2914)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.ListView.scrollListItemsBy(ListView.java:2843)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.ListView.arrowScrollImpl(ListView.java:2340)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.ListView.arrowScroll(ListView.java:2287)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.ListView.commonKey(ListView.java:2089)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.ListView.onKeyDown(ListView.java:2036)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.KeyEvent.dispatch(KeyEvent.java:1256)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.View.dispatchKeyEvent(View.java:3855)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:787)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.widget.ListView.dispatchKeyEvent(ListView.java:2021)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1687)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1120)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.app.Activity.dispatchKeyEvent(Activity.java:2073)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2560)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2535)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.os.Handler.dispatchMessage(Handler.java:99)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.os.Looper.loop(Looper.java:123)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at android.app.ActivityThread.main(ActivityThread.java:3683)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at java.lang.reflect.Method.invokeNative(Native Method)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at java.lang.reflect.Method.invoke(Method.java:507)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    11-27 11:06:09.680:
    ERROR/java.lang.NullPointerException(536): at dalvik.system.NativeStart.main(Native Method)
    c

  8. Hello
    I think I solved the above exception but another one has cropped up, any ideas please….

    11-28 12:17:55.585: ERROR/org.json.JSONException(446): Value null of type org.json.JSONObject$1 cannot be converted to JSONArray
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): org.json.JSONException: Value null of type org.json.JSONObject$1 cannot be converted to JSONArray
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at org.json.JSON.typeMismatch(JSON.java:107)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at org.json.JSONArray.(JSONArray.java:91)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at org.json.JSONArray.(JSONArray.java:103)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at com.isummation.listview.MyListView.getJobs(MyListView.java:415)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at com.isummation.listview.MyListView$JobListAdapter.addMoreData(MyListView.java:157)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at com.isummation.listview.MyListView$JobListAdapter$addMoreData.doInBackground(MyListView.java:314)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at com.isummation.listview.MyListView$JobListAdapter$addMoreData.doInBackground(MyListView.java:1)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at android.os.AsyncTask$2.call(AsyncTask.java:185)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
    11-28 12:17:55.585: ERROR/org.json.JSONException(446): at java.lang.Thread.run(Thread.java:1019)
    11-28 12:17:55.832: WARN/dalvikvm(446): threadid=13: thread exiting with uncaught exception (group=0x40015560)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): FATAL EXCEPTION: AsyncTask #5
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): java.lang.RuntimeException: An error occured while executing doInBackground()
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at android.os.AsyncTask$3.done(AsyncTask.java:200)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.lang.Thread.run(Thread.java:1019)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): Caused by: java.lang.RuntimeException: Can’t create handler inside thread that has not called Looper.prepare()
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at android.os.Handler.(Handler.java:121)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at android.widget.Toast.(Toast.java:68)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at android.widget.Toast.makeText(Toast.java:231)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at com.isummation.listview.MyListView$JobListAdapter$addMoreData.doInBackground(MyListView.java:318)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at com.isummation.listview.MyListView$JobListAdapter$addMoreData.doInBackground(MyListView.java:1)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at android.os.AsyncTask$2.call(AsyncTask.java:185)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
    11-28 12:17:55.874: ERROR/AndroidRuntime(446): … 4 more

  9. Hello
    Is there a way in your initialize() method of displaying a progress dialog just before it loads in data as it takes 4/6 seconds to load. I have tried a Async class but getjobs() returned null when called from the doInBackground method of the async class. thanks

    1. P.s. here is my current code:
      private class xyz extends AsyncTask {
      private final ProgressDialog dialog = new ProgressDialog(EventsWall.this);
      private JSONArray jArray;
      protected void onPreExecute() {
      this.dialog.setMessage(“Loading Events…Please Wait…”);
      this.dialog.show();
      }

      @Override
      protected Void doInBackground(Void… arg0) {
      // make code which you want in background
      lastDate = null;
      // mSeparatorsSet.clear();
      //mData.clear();
      jArray = getJobs(1);
      //ParseJSONArray(JQueryData);
      return null;
      }

      protected void onPostExecute(final Void unused) {
      if (dialog.isShowing()) {
      dialog.dismiss();
      }
      ParseJSONArray(jArray);
      //runOnUiThread(new Runnable() {
      // public void run() {
      //jobListAdapter.notifyDataSetChanged();
      // }
      //});
      }
      }

  10. Extremely helpful! Thanks. This is essentially exactly what I needed to do, I was only trying to set a “loader” for the listview content, but you included the JSON as well. Nifty.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s