Reputation: 5089
I have this peace of code, that fetches some xml data from an url.
It does it's job properly but the problem is that while it downloads and parses xml the UI freezes, and that might be a problem for the users.
Here is the class
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.kategoria);
// getting intent data
Intent in = getIntent();
String cat_name = in.getStringExtra("kategoria");
//Update Textview
TextView kategoriatw = (TextView)findViewById(R.id.name_of_cat);
kategoriatw.setText(cat_name);
// Kategoro URL
String catUrl = "http://sample.com/xmldata.xml";
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
//MOTHERLAJME MULTIDIMENSIONAl
final List<HashMap<String, String>> MotherContainer= new ArrayList<HashMap<String, String>>();
try{
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(catUrl); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
//ALL
NodeList forecastW = doc.getElementsByTagName("newsitem");
for (int j = 0; j < forecastW.getLength(); j++)
{
HashMap<String, String> map = new HashMap<String, String>();
Node nodeday = forecastW.item(j);
Element dayElmnt = (Element) nodeday;
map.put("title", (parser.getValue(dayElmnt, "title")) );
map.put("intro", (parser.getValue(dayElmnt, "intro")).toString());
map.put("story_id", ""+j );
// adding HashList to ArrayList
menuItems.add(map);
//MULTI DIMENSIONAL ARRAY
HashMap<String, String> TheStory= new HashMap<String, String>();
TheStory .put("title", (parser.getValue(dayElmnt, "title")));
TheStory .put("story_date", parser.getValue(dayElmnt, "datetime"));
MotherContainer.add(j, TheStory);
/////////////////////////
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(this, menuItems,
R.layout.week_day_item,
new String[] { "title", "intro", "story_id"}, new int[] {
R.id.title_list,
R.id.intro_list,
R.id.story_id_list});
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleLajm.class);
//start new intent....
startActivity(in);
}
});
}
I want to use Asynctask so that the UI won't freeze and Im using this on my class, this is the "updated" version of the class that Im using, that implements async:
Document doc;
String xml;
ListView lv;
//ListViewAdapter adapter;
//ArrayList<HashMap<String, String>> menuItems;
ProgressDialog pDialog;
final ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
//MOTHERLAJME MULTIDIMENSIONAl
final List<HashMap<String, String>> MotherLajme= new ArrayList<HashMap<String, String>>();
final HashMap<String, String> nrLajmit = new HashMap<String, String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.kategoria);
// getting intent data
Intent in = getIntent();
// Get emr
String catname = in.getStringExtra("kategoria");
//Textview
TextView kategoriatw = (TextView)findViewById(R.id.kategoria_emri);
kategoriatw.setText(catname);
}
private class loadMoreListView extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(
Kategoria.this);
pDialog.setMessage("Please wait..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
}
protected Void doInBackground(Void... unused) {
new Runnable() {
public void run() {
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl("http://sample.com/data.xml"); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
//ALL
NodeList forecastW = doc.getElementsByTagName("newsitem");
for (int j = 0; j < forecastW.getLength(); j++)
{
HashMap<String, String> map = new HashMap<String, String>();
Node nodeday = forecastW.item(j);
Element dayElmnt = (Element) nodeday;
map.put("title", (parser.getValue(dayElmnt, "title")) );
map.put("intro", (parser.getValue(dayElmnt, "intro")) );
map.put("story_id", ""+j );
// adding HashList to ArrayList
menuItems.add(map);
//MULTI DIMENSIONAL ARRAY
HashMap<String, String> TheLajmi= new HashMap<String, String>();
TheLajmi .put("title", (parser.getValue(dayElmnt, "title")));
TheLajmi .put("newsdate", parser.getValue(dayElmnt, "datetime"));
MotherLajme.add(j, TheLajmi);
/////////////////////////
}
}
};
return (null);
}
protected void onPostExecute(Void unused) {
// closing progress dialog
pDialog.dismiss();
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(Kategoria.this, menuItems,
R.layout.week_day_item,
new String[] { "title", "intro", "story_id"}, new int[] {
R.id.title_list,
R.id.intro_list,
R.id.story_id_list});
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleLajm.class);
in.putExtra("title", "blabla");
startActivity(in);
}
});
}
}
But I can't get it to work. All I see is either a blank page or some error that I cannot edit the views.
Can someone help to solve this issue?
Thanks.
Upvotes: 0
Views: 1204
Reputation: 11948
try following code:
private class LoadMoreListView extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
@Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(
AndroidListViewWithLoadMoreButtonActivity.this);
pDialog.setMessage("Please wait..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
}
protected ArrayList<HashMap<String, String>> doInBackground(Void... unused) {
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
//MOTHERLAJME MULTIDIMENSIONAl
final List<HashMap<String, String>> MotherContainer= new ArrayList<HashMap<String, String>>();
try{
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(catUrl); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
//ALL
NodeList forecastW = doc.getElementsByTagName("newsitem");
for (int j = 0; j < forecastW.getLength(); j++)
{
HashMap<String, String> map = new HashMap<String, String>();
Node nodeday = forecastW.item(j);
Element dayElmnt = (Element) nodeday;
map.put("title", (parser.getValue(dayElmnt, "title")) );
map.put("intro", (parser.getValue(dayElmnt, "intro")).toString());
map.put("story_id", ""+j );
// adding HashList to ArrayList
menuItems.add(map);
//MULTI DIMENSIONAL ARRAY
HashMap<String, String> TheStory= new HashMap<String, String>();
TheStory .put("title", (parser.getValue(dayElmnt, "title")));
TheStory .put("story_date", parser.getValue(dayElmnt, "datetime"));
MotherContainer.add(j, TheStory);
/////////////////////////
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
return menuItems;
}
protected void onPostExecute(ArrayList<HashMap<String, String>> unused) {
// closing progress dialog
pDialog.dismiss();
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(YourActivity.this, unused,
R.layout.week_day_item,
new String[] { "title", "intro", "story_id"}, new int[] {
R.id.title_list,
R.id.intro_list,
R.id.story_id_list});
setListAdapter(adapter);
}
In AsyncTask
1st param means the type you can pass to execute. Void means you can pass nothing
The class names in Java should start with upper-calse letter. Please rename it for better readability by others.
So proper call would be
new LoadMoreListView().execute();
2nd param is a type of data you can publish calling publishProgress()
from doInBackground()
. You don't use publishProgress
, so nothing to mention in this case.
3rd param mean s type that will be passed to onPostExecute()
. To pass the menuItems to onPostExecute you must return it from doInBackground. so you need declare your class with
AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>
doInBackground runs on new thread so you don't need following code:
new Runnable() {
public void run()
if you want work with UI thread you can use following method:
onPreExecute
onPostExecute
onPreExecute
usually used for showing please wait dialog or something like that and onPostExecute
used for showing data after downloading and other thing
Upvotes: 5