android.os.networkexception on Main method [duplicate] - android

This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 9 years ago.
Below is my code:
private static final String TAG_TYPE = "movie_type";
private static final String TAG_NAME = "movie_name";
private static final String TAG_LENGTH = "movie_length";
private static final String TAG_SCHEDULES = "movie_schedules";
private static final String TAG_CINEMA = "movie_cinema_number";
private static final String TAG_URL = "movie_image_url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
String readMovieSchedules = readMovieSchedules();
// Hashmap for ListView
ArrayList<HashMap<String, String>> movieList = new ArrayList<HashMap<String, String>>();
JSONArray jsonArray = new JSONArray(readMovieSchedules);
Log.i(MainActivity.class.getName(),
"Number of entries " + jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.i(MainActivity.class.getName(), jsonObject.getString("movie_name"));
// Storing each json item in variable
String name = jsonObject.getString(TAG_NAME);
String type = jsonObject.getString(TAG_TYPE);
String length = jsonObject.getString(TAG_LENGTH);
String cinema = jsonObject.getString(TAG_CINEMA);
String schedules = jsonObject.getString(TAG_SCHEDULES);
String url = jsonObject.getString(TAG_URL);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_NAME, name);
map.put(TAG_TYPE, type);
map.put(TAG_LENGTH, length);
map.put(TAG_CINEMA, cinema);
map.put(TAG_SCHEDULES, schedules);
map.put(TAG_URL, url);
// adding HashList to ArrayList
movieList.add(map);
//String strURL = TAG_URL.replaceAll(" ", "%20");
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(MainActivity.this, movieList,
R.layout.list_item,
new String[] { TAG_NAME, TAG_CINEMA, TAG_SCHEDULES },
new int[] { R.id.name, R.id.cinema, R.id.schedules });
//new String[] {},
//new int[] {});
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
String cost = ((TextView) view.findViewById(R.id.cinema)).getText().toString();
String description = ((TextView) view.findViewById(R.id.schedules)).getText().toString();
//String url = ((TextView) view.findViewById(R.id.image_)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_CINEMA, cost);
in.putExtra(TAG_SCHEDULES, description);
//in.putExtra(TAG_URL, url);
startActivity(in);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
This code is working on SDK 8, but not working on 17. I'm stuck with this problem. Does anyone here know how to debug this? I'd gladly appreciate your help. thanks.

You can't make network calls on the main thread since API 11 (3.0). Read more here:
http://www.androiddesignpatterns.com/2012/06/app-force-close-honeycomb-ics.html

You have to put your code inside an AsyncTask , it is forbidden to download anything on the main UI thread since API 14 I believe.
It would be something like this:
public class someTask extends AsyncTask<String, Void, String> {
public MainActivity activity;
public someTask(MainActivity a)
{
activity = a;
}
#Override
protected String doInBackground(String... urls) {
String stringtoparse=null;
for (String url : urls) {
stringtoparse= readMovieSchedules(url); // getting XML from URL
}
return stringtoparse;
}
#Override
protected void onPreExecute(){
}
#Override
protected void onPostExecute(String readMovieSchedules) {
// Hashmap for ListView
ArrayList<HashMap<String, String>> movieList = new ArrayList<HashMap<String, String>>();
JSONArray jsonArray = new JSONArray(readMovieSchedules);
Log.i(MainActivity.class.getName(),
"Number of entries " + jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.i(MainActivity.class.getName(), jsonObject.getString("movie_name"));
// Storing each json item in variable
String name = jsonObject.getString(TAG_NAME);
String type = jsonObject.getString(TAG_TYPE);
String length = jsonObject.getString(TAG_LENGTH);
String cinema = jsonObject.getString(TAG_CINEMA);
String schedules = jsonObject.getString(TAG_SCHEDULES);
String url = jsonObject.getString(TAG_URL);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_NAME, name);
map.put(TAG_TYPE, type);
map.put(TAG_LENGTH, length);
map.put(TAG_CINEMA, cinema);
map.put(TAG_SCHEDULES, schedules);
map.put(TAG_URL, url);
// adding HashList to ArrayList
movieList.add(map);
}
}
You have to modify the readMovieSchedules() to take the url as an argument like this readMovieSchedules(url) and I think it'll work just fine, you would call the task like this:
getMovieSched task = new someTask(MainActivity.this);
task.execute(url);

ASyncTask is specifically made for scenarios like this. It allows you to communicate over the network in a seperate thread without you needing to work with threads.
ASyncTask has these methods :
onPreExecute() : this is invoked before the main processing happens ... one use of it would be to start the progress dialog notifying the user of the transaction.
doInBackground() : this is where you perform data exchange from the network . no UI fiddling around here.
onProgressUpdate() : can be used to notify progress of the transaction
onPostExecute() : dismiss the progressDialogs/bars and update your views from the fetched data!
another solution would be to use runOnUiThread() but this is discouraged!
class nwthread extends AsyncTask<Void,Void,Void>
{
#Override
protected void onPreExecute() {
//progress dialog invoke ( notifies the user about whats going on better than making them stare on a blank screen)
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
//make http request/parse json here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//dismiss progress dialog
// update the UI here ... ie declare adapters / bind them, update other views
}
}
finally invoke nwthread.execute(); after setContentView();

Related

How do I refresh the data in the ListView?(json&http)

First of all , there is a listview in the activity named "user" . In the activity class, I have a thread that runs every 10 seconds. The thread calls a function which executes an AsyncTask . The AsyncTask does an http request and the response is parsed by a class named JSONparse . The data is then used in a listview inside a for loopwith a simple adapter.
The actual problem here is that the older data stay in the listview , and the same elements are added every 10 seconds.
The onPostExecute is inside the JSONparse class:
private static final String TAG_OS = "istekler";
private static final String TAG_VER = "isim";
private static final String TAG_NAME = "istek";
private static final String TAG_API = "mesaj";
protected void onPostExecute(JSONObject json) {
try {
// Getting JSON Array from URL
android = json.getJSONArray(TAG_OS);
for(int i = 0; i < android.length(); i++){
JSONObject c = android.getJSONObject(i);
// Storing JSON item in a Variable
String isim = c.getString(TAG_VER);
String mesaj = c.getString(TAG_NAME);
String istek = c.getString(TAG_API);
// Adding value HashMap key => value
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_VER, isim);
map.put(TAG_NAME, mesaj);
map.put(TAG_API, istek);
oslist.add(map);
list=(ListView)findViewById(R.id.list);
ListAdapter adapter = new SimpleAdapter(user.this, oslist,
R.layout.list_v,
new String[] { TAG_VER,TAG_NAME, TAG_API }, new int[] {
R.id.isim,R.id.mesaj, R.id.istek});
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(user.this, "Parça: "+oslist.get(+position).get("istek"), Toast.LENGTH_SHORT).show();
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}
on your code you just add new elements to your list. You should call oslist.clear() to remove the old data.

Android JSON ListView import

I'm slowly turning crazy here.
I've got NewsActivity that gets information from a website and puts it in the listview but it isn't working.
public class NewsActivity extends ListActivity {
private ProgressDialog pDialog;
// URL to get contacts JSON
private static String NEWS_URL = "http://www.bandofbrothersgaming.nl/android/news.php";
// JSON Node names
private static final String TAG_POSTID = "sid";
private static final String TAG_POSTSUBJECT = "title";
private static final String TAG_POSTTEXT = "hometext";
// contacts JSONArray
JSONArray post_id = null;
// Hashmap for ListView
ArrayList < HashMap < String, String >> NewsList;
#
Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
NewsList = new ArrayList < HashMap < String, String >> ();
ListView lv = getListView();
// Listview on item click listener
lv.setOnItemClickListener(new OnItemClickListener() {
#
Override
public void onItemClick(AdapterView <? > parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.post_id))
.getText().toString();
String cost = ((TextView) view.findViewById(R.id.post_subject))
.getText().toString();
String description = ((TextView) view.findViewById(R.id.post_text))
.getText().toString();
// Starting single contact activity
/* Intent in = new Intent(getApplicationContext(),
SingleContactActivity.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_EMAIL, cost);
in.putExtra(TAG_PHONE_MOBILE, description);
startActivity(in);*/
}
});
// Calling async task to get json
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class GetContacts extends AsyncTask < Void, Void, Void > {
#
Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(NewsActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#
Override
protected Void doInBackground(Void...arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(NEWS_URL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
post_id = jsonObj.getJSONArray(TAG_POSTID);
// looping through All Posts
for (int i = 0; i < post_id.length(); i++) {
JSONObject c = post_id.getJSONObject(i);
String postid = c.getString(TAG_POSTID);
String postsubject = c.getString(TAG_POSTSUBJECT);
String posttext = c.getString(TAG_POSTTEXT);
// tmp hashmap for single contact
HashMap < String, String > contact = new HashMap < String, String > ();
// adding each child node to HashMap key => value
contact.put(TAG_POSTID, postid);
contact.put(TAG_POSTSUBJECT, postsubject);
contact.put(TAG_POSTTEXT, posttext);
// adding contact to contact list
NewsList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#
Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
NewsActivity.this, NewsList,
R.layout.list_item, new String[] {
TAG_POSTID, TAG_POSTSUBJECT,
TAG_POSTTEXT
}, new int[] {
R.id.post_id,
R.id.post_subject, R.id.post_text
});
setListAdapter(adapter);
}
}
}
When I run it LogCat says the following :
12-29 13:56:39.698: W/System.err(1685): org.json.JSONException: Value [{"hometext":"Welcome to Nuke-Evolution.<br \/><br \/>\r\n\r\nYou must now setup an admin account. You can do this by <a href=\"admin.php\">clicking here<\/a>.<br \/><br \/><br \/><br \/>\r\n\r\n<b>NOTE:<\/b> You can remove this by going into the News Administration or by clicking the delete button below.\r\n","sid":"1","time":"2005-07-02 10:38:28","title":"Welcome To Nuke-Evolution"},{"hometext":"<p>\n\ttest android<\/p>\n<p>\n\tandroid test<\/p>","sid":"2","time":"2014-12-28 23:21:25","title":"android test"}] of type org.json.JSONArray cannot be converted to JSONObject
Does anybodey knows what im doing wrong?
You are trying to convert jsonStr to a JSONObject, but in fact is a JSONArray, looking at the LogCat. So convert it to a JSONArray first, then iterate over it and get the data you are looking for.
You can use
JSONArray post_id = new JSONArray(jsonStr);
instead of
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
post_id = jsonObj.getJSONArray(TAG_POSTID);
because jsonStr you get is a JSONArray
That is response of you php file, review your code PHP.
try this
JSONArray jsonArr = new JSONArray(jsonStr);
for(int i = 0; i < jsonArr.length(); i++){
JSONObject item = jsonArr.getJSONObject(i);
String postid = item.getString(TAG_POSTID);
String postsubject = item.getString(TAG_POSTSUBJECT);
String posttext = item.getString(TAG_POSTTEXT);
// tmp hashmap for single contact
HashMap < String, String > contact = new HashMap < String, String > ();
// adding each child node to HashMap key => value
contact.put(TAG_POSTID, postid);
contact.put(TAG_POSTSUBJECT, postsubject);
contact.put(TAG_POSTTEXT, posttext);
// adding contact to contact list
NewsList.add(contact);
}

Loading image in ListView from Array ID Android

I currently have a ListAdapter set up that is passed information pulled from a MYSQL database via JSON. I'm trying to display an image I have stored in the drawable folder based on the ID of the product. e.g For Product 1 R.drawable.img1 is shown in and so on..
public class GetProducts extends ListActivity {
// Progress Dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSON jParser = new JSON();
Functions uf = new Functions();
ArrayList<HashMap<String, Object>> productsList;
// url to get all products list
private static String url_all_products = "http://jumpto.be/api/get_all_products.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCTS = "products";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";
private static final String TAG_IMGURL = "image";
// products JSONArray
JSONArray products = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_products);
// Hashmap for ListView
productsList = new ArrayList<HashMap<String, Object>>();
new GetProductsFromDB().execute();
// Loading products in Background Thread
// Get listview
ListView lv = getListView();
// on seleting single product
// launching Edit Product Screen
/*lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String pid = ((TextView) view.findViewById(R.id.pid)).getText()
.toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),
OrderBuild.class);
// sending pid to next activity
in.putExtra(TAG_PID, pid);
// starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});*/
}
class GetProductsFromDB extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(GetProducts.this);
pDialog.setMessage("Loading products. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url_all_products, params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String ImgUrl = c.getString(TAG_PID);
// creating new HashMap
HashMap<String, Object> map = new HashMap<String, Object>();
// adding each child node to HashMap key => value
map.put(TAG_PID, id);
map.put(TAG_NAME, name);
String imageLink = "R.drawable.img"+id;
map.put(TAG_IMGURL, imageLink);
// adding HashList to ArrayList
productsList.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(
GetProducts.this, productsList,
R.layout.list_item, new String[] { TAG_PID,
TAG_NAME, TAG_IMGURL},
new int[] { R.id.pid, R.id.name, R.id.img });
// updating listview
setListAdapter(adapter);
}
});
}
}
}
The current code I have just tells me it cannot find the directory. I have looked at URI but I can't figure out how I run them in the array / for loop.
Many Thanks
R.drawable.img1 is actually just an int value defined in your automatically generated R.java file, so you cannot use it directly.
However, you can retrieve your drawable using the following:
Resources resources = getResources();
int resId = resources.getIdentifier("img" + id, "drawable", getPackageName());
Drawable myDrawable = resources.getDrawable(resId);
Alternatively, you can place your image files in your assets directory and load them from there using the filename.
InputStream inputStream = getAssets().open("img" + id + ".jpg");
Drawable drawable = Drawable.createFromStream(inputStream, null);
mImageView.setImageDrawable(drawable);
You can set int value for drawable in hashmap. It is easy to bind in list adapter.
int imageLink = R.drawable.img1;
map.put(TAG_IMGURL, imageLink);

Is it Possible to get results of AsyncTask as an Arraylist Hashmap

I have at least three activities in my app right now that use an AsyncTask to return JSON results into an ListView. I've started work on the app, but another person will take over development as soon as he gets the basics down, so I want to try and make things as easy to use as possible. This means that I'm trying to turn as much repeatable code into callable functions as possible, so instead of needing to copy/paste/reuse 30-40 lines of code each time they need query a webservice, they can just pass in parameters to a function.
Currently, I have the following in an activity that pulls a list of gym classes from a mysql database via a php webservice:
class LoadAllClasses extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
// pDialog = new ProgressDialog(Checkin.this);
// pDialog.setMessage("Loading products. Please wait...");
// pDialog.setIndeterminate(false);
// pDialog.setCancelable(false);
// pDialog.show();
}
/**
* getting All products from url
* */
#Override
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", getclasses_tag));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(SmashGyms.WEBSERVICE_URL,
"POST", params);
// Check your log cat for JSON response
Log.d("CheckinDialog", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// classes found
// Getting Array of Classes
classes2 = json.getJSONArray(TAG_CLASSES);
// looping through All Classes
for (int i = 0; i < classes2.length(); i++) {
JSONObject c = classes2.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_CLASSID);
String name = c.getString(TAG_CLASSNAME);
//String day = c.getString(TAG_DAY);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_CLASSID, id);
map.put(TAG_CLASSNAME, name);
//map.put(TAG_DAY, day);
// adding HashList to ArrayList
allclasseslist.add(map);
Log.d("map: ", map.toString());
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
runOnUiThread(new Runnable() {
#Override
public void run() {
/**
* Updating parsed JSON data into ListView
* */
adapter = new SimpleAdapter(CheckinDialog.this,
allclasseslist, R.layout.checkin_item,
new String[] { TAG_CLASSID, TAG_CLASSNAME },
new int[] { R.id.pid, R.id.name });
setListAdapter(adapter);
}
});
//pDialog.dismiss();
// updating UI from Background Thread
}
}
I'd like to move this to another class that I have, called "WebServiceTasks", so that I can call something like this in the activity's OnCreate():
allclasseslist = new ArrayList<HashMap<String, String>>();
allclasseslist = new WebServiceTasks.LoadAllClasses().get();
adapter = new SimpleAdapter(CheckinDialog.this,
allclasseslist, R.layout.checkin_item,
new String[] { TAG_CLASSID, TAG_CLASSNAME },
new int[] { R.id.pid, R.id.name });
setListAdapter(adapter);
While I've tried this, I get a number of errors related to either defining the asyncTask wrong, or other things not matching up.
Here is what I've tried putting in my "WebServiceTasks" class:
public static class LoadAllClasses extends
AsyncTask<String, String, ArrayList<HashMap<String, String>>> {
JSONParser jParser = new JSONParser();
ArrayList<HashMap<String, String>> allclasseslist;
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_CLASSES = "classes";
private static final String TAG_CLASSID = "id";
private static final String TAG_CLASSNAME = "class";
private static final String getclasses_tag = "getclasses";
JSONArray classes2 = null;
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
// pDialog = new ProgressDialog(Checkin.this);
// pDialog.setMessage("Loading products. Please wait...");
// pDialog.setIndeterminate(false);
// pDialog.setCancelable(false);
// pDialog.show();
}
/**
* getting All classes from url
* */
#Override
protected ArrayList<HashMap<String, String>> doInBackground(
String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", getclasses_tag));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(SmashGyms.WEBSERVICE_URL,
"POST", params);
// Check your log cat for JSON response
Log.d("CheckinDialog", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// classes found
// Getting Array of Classes
classes2 = json.getJSONArray(TAG_CLASSES);
// looping through All Classes
for (int i = 0; i < classes2.length(); i++) {
JSONObject c = classes2.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_CLASSID);
String name = c.getString(TAG_CLASSNAME);
//String day = c.getString(TAG_DAY);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_CLASSID, id);
map.put(TAG_CLASSNAME, name);
//map.put(TAG_DAY, day);
// adding HashList to ArrayList
allclasseslist.add(map);
Log.d("map: ", map.toString());
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return allclasseslist;
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(
ArrayList<HashMap<String, String>> allclasses) {
// dismiss the dialog after getting all products
//pDialog.dismiss();
// updating UI from Background Thread
}
}
Is this possible, and if so, what am I doing wrong?
Well, you are trying to use get() method of AsyncTask which is very expensive because it blocks the UI until your onPostExecute() is completed. I would insist you to fire a BroadCastReceiver in onPostExecute() to update your UI or create and Interface and pass the result to your Activity using that interface in your onPostExecute(). I had just created a small demo for using BroadCastReceiver and Interface for passing result from onPostExecute() to your Activity. You can find a demo source from my github here.
You Can Create A Bean class to store all the values from async task so that your can receive it to another class my friend
For anyone trying to replicate this, Here is how I solved this, using Lalit and Samir's examples:
In my Activity:
public class CheckinDialog extends ListActivity implements
AsyncTaskCompleteListener {
WebServiceTasks.LoadAllClasses objAsyncTask = new WebServiceTasks.LoadAllClasses(
this);
objAsyncTask.execute();
#Override
public void onTaskComplete(ArrayList<HashMap<String, String>> allclasseslist) {
// TODO Auto-generated method stub
adapter = new SimpleAdapter(CheckinDialog.this, allclasseslist,
R.layout.checkin_item, new String[] { TAG_CLASSID,
TAG_CLASSNAME }, new int[] { R.id.pid, R.id.name });
setListAdapter(adapter);
Log.d("OnTaskComplete", "taskcomplete");
}
In an interface called "AsyncTaskCompleteListener":
public interface AsyncTaskCompleteListener {
void onTaskComplete(ArrayList<HashMap<String, String>> allclasseslist);
}
And the seperate WebServiceTasks Class:
public static class LoadAllClasses extends
AsyncTask<String, String, ArrayList<HashMap<String, String>>> {
JSONParser jParser = new JSONParser();
private final AsyncTaskCompleteListener callback;
private final Activity activity;
public LoadAllClasses(Activity act) {
this.activity = act;
this.callback = (AsyncTaskCompleteListener) act;
}
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_CLASSES = "classes";
private static final String TAG_CLASSID = "id";
private static final String TAG_CLASSNAME = "class";
private static final String getclasses_tag = "getclasses";
JSONArray classes2 = null;
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* getting All classes from url
* */
#Override
protected ArrayList<HashMap<String, String>> doInBackground(
String... args) {
// Building Parameters
ArrayList<HashMap<String, String>> allclasseslist = null;
allclasseslist = new ArrayList<HashMap<String, String>>();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", getclasses_tag));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(SmashGyms.WEBSERVICE_URL,
"POST", params);
// Check your log cat for JSON response
Log.d("CheckinDialog", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// classes found
// Getting Array of Classes
classes2 = json.getJSONArray(TAG_CLASSES);
Log.d("JSONArray", json.getJSONArray(TAG_CLASSES)
.toString());
// looping through All Classes
for (int i = 0; i < classes2.length(); i++) {
JSONObject c = classes2.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_CLASSID);
String name = c.getString(TAG_CLASSNAME);
//String day = c.getString(TAG_DAY);
// creating new HashMap
final HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_CLASSID, id);
map.put(TAG_CLASSNAME, name);
//map.put(TAG_DAY, day);
// adding HashList to ArrayList
allclasseslist.add(map);
//Log.d("map: ", map.toString());
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return allclasseslist;
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(
ArrayList<HashMap<String, String>> allclasseslist) {
super.onPostExecute(allclasseslist);
// dismiss the dialog after getting all classes
callback.onTaskComplete(allclasseslist);
}
}
Thanks to all for the quick help. This ended up saving over 120 lines of repeating code in each activity that used this code.

Setonitemclicklistener with AsyncTask gives NullPointerException

Need your help!!!
I have activity, where I get some data in JSON format and put it ListView. Everything works fine. But I want to define what item was clicked in list with Setonitemclicklistener. I tried to use it in onPostExecuted() method of my inner Connection class,which extends AsyncTask, but I've got NullPoinerException
public class ConnectionActivity extends ListActivity{
JsonParser jsonParser = new JsonParser();
private ListView listView;
JSONArray inbox = null;
private ProgressDialog pDialog;
private static final String TAG_ID = "ID";
private static final String TAG_NAME = "Date";
private static final String TAG_DATE = "Name";
private static final String TAG_PRICE = "Price";
ArrayList<HashMap<String,String>> resultList;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
resultList = new ArrayList<HashMap<String,String>> ();
new Connection().execute();
new ListHandler().execute();
}
class Connection extends AsyncTask<String,String,String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ConnectionActivity.this);
pDialog.setMessage("Не базарь и жди пока загрузиться!!!!");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
String json = jsonParser.makeHttpRequest();
Log.d("Outbox JSON",json.toString());
try{
JSONArray jArray = new JSONArray(json);
for (int i=0;i<jArray.length();i++) {
JSONObject c = jArray.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name= c.getString(TAG_NAME);
String date = c.getString(TAG_DATE);
String price = c.getString(TAG_PRICE);
// creating new HashMap
HashMap<String, String> hashmap = new HashMap<String, String>();
// adding each child node to HashMap key => value
hashmap.put(TAG_ID, id);
hashmap.put(TAG_NAME, name);
hashmap.put(TAG_DATE, date);
hashmap.put(TAG_PRICE, price);
// adding HashList to ArrayList
resultList.add(hashmap);
}
}
catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
ConnectionActivity.this, resultList,
R.layout.connect_item, new String[] { TAG_ID, TAG_NAME, TAG_DATE, TAG_PRICE },
new int[] { R.id.order_id, R.id.order_date, R.id.order_name, R.id.order_price });
// updating listview
setListAdapter(adapter);
listView = (ListView) findViewById(R.id.list);
listView.setOnItemClickListener(new ListClickListener());
}
});
}
}
I think that problem is with using of one thread, so I created one more inner class in my ConnectionActivity like this^
class ListHandler extends AsyncTask<Void,Void,Void>
{
protected void onPreExecute ()
{
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
return null;
}
protected void onPostExecute()
{
listView = (ListView) findViewById(R.id.list);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View view, int position, long arg) {
Log.d("Click on the item","!!!!!!!!!!!!!!!!!!!!!");
Toast toast = Toast.makeText(getApplicationContext(),
"Пора покормить кота!", Toast.LENGTH_SHORT);
toast.show();
}
});
}
}
But it doesn't work. I mean that I cannot get the Toast when I clicked on the item , but there's no exception. I tried to handle setonitemclicklistener in void onResume() method of the Activity, but I've got NullPointerException. Also I handled this in OnPreExecute() method of the ListHandler class - same result...
Help please with it...
where is setContentView(R.layout.yourxml) ? i think you forgot it in oncreate Method.
So your listView is null and gives NPE.
AND
onPostExecute method have runonUiThread,Remove it no need it.Its already run in UI Thread.
Problem solved with extending from Activity instead of ListActivity and using setContentView().

Categories

Resources