I get some json data from server using AsyncTask and put it in a ListView using an ArrayAdapter. As I am getting a lot of data, please tell me how can I add an infinite scroll to my ListView. I mean to say, that when the ListView reaches its end, the data should be loaded automatically. I searched the web and tried a lot of things but can't do what I want to.
Here is my code
public class Main extends Activity {
ArrayList<ContentSetter> postList;
StringArrayAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
postList = new ArrayList<>();
new GetData().execute();
ListView lv = (ListView) findViewById(R.id.list);
Button btnLoadMore = new Button(this);
btnLoadMore.setText("Load More");
lv.addFooterView(btnLoadMore);
adapter = new StringArrayAdapter(getApplicationContext(), R.layout.row, postList);
lv.setAdapter(adapter);
}
class GetData extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(Main.this);
dialog.setMessage("Loading, please wait");
dialog.setTitle("Connecting server");
dialog.show();
dialog.setCancelable(false);
}
#Override
protected Boolean doInBackground(String... params) {
HttpURLConnection urlConnection;
int pageed;
String result = "";
try {
URL url = new URL("http://paradi3emusic.com/?json=get_posts&post_type=songs&count=15");
urlConnection = (HttpURLConnection) url.openConnection();
int code = urlConnection.getResponseCode();
if(code==200){
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = bufferedReader.readLine()) != null)
result += line;
JSONObject jsono = new JSONObject(result);
JSONArray jarray = jsono.getJSONArray("posts");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
ContentSetter content = new ContentSetter();
JSONObject customfield = object.getJSONObject("custom_fields");
JSONArray playlist = customfield.getJSONArray("mylyrics1");
content.setPostId(playlist.getString(0));
postList.add(content);
}
in.close();
return true;
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Connecting err.", Toast.LENGTH_LONG).show();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
adapter.notifyDataSetChanged();
//TextView mahd = (TextView)findViewById(R.id.mahdi);
if (!result)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server.", Toast.LENGTH_LONG).show();
}
}
}
This concept is called lazy loading.
you need to do something like this:
listen for the event when user scrolls to the end of listview
make your webservice call and show user a progressbar at the footer of list.
update list with data once data is received from service call, remove progressbar.
here is an example
This feature is something similar to Pageing. What you need to do is :
1) Listen for event when user scroll to Bottom of Listview
2) Pull more data from server or any other source you want to.
3) When request is being made put some footer to your listview,example showing some progress dialog for user friendliness.
4) Update the data source with pulled information
5) Set and Update your adapter and remove the footer from the listview and You are done.
For Your Reference check this link:
https://chrisarriola.wordpress.com/2012/06/15/dynamic-data-with-listview-loading-footer/
Related
Hello I'm new at android. There is a arrayList and a ListView. I used AsyncTask class to invoke the database from MYSQL DB. This AsyncTask class sets mArrayList(this is the arrayList). To update the list view when I return from another activity, I used onResume(). This is the part.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mold_breakage_history);
brokenMoldListView = findViewById(R.id.brokenMoldListView);
mArrayList = new ArrayList<>();
GetData task = new GetData();
task.execute("http://www.cafe24.com/aaa.php");
}
#Override
protected void onResume() {
super.onResume();
mArrayList = new ArrayList<>();
GetData task = new GetData();
task.execute("http://www.cafe24.com/aaa.php");
In onResume(), I initialized the mArrayList and invoke AsyncTask again to update ListView. The problem is when this activity was first executed, the ListView was duplicated. But, when I back from next page of this Activity, the problem is disappeared. I hope that this issue is not present when activity is first executed. Please help.
This is code of AsyncTask class.
#SuppressLint("StaticFieldLeak")
private class GetData extends AsyncTask<String, Void, String> {
ProgressDialog progressDialog;
String errorString = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(MoldBreakageHistoryActivity.this,
"Please Wait", null, true, true);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.dismiss();
Log.d(TAG, "response - " + result);
mJsonString = result;
showResult();
}
#Override
protected String doInBackground(String... params) {
String serverURL = params[0];
try {
URL url = new URL(serverURL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setReadTimeout(5000);
httpURLConnection.setConnectTimeout(5000);
httpURLConnection.connect();
int responseStatusCode = httpURLConnection.getResponseCode();
Log.d(TAG, "response code - " + responseStatusCode);
InputStream inputStream;
if (responseStatusCode == HttpURLConnection.HTTP_OK) {
inputStream = httpURLConnection.getInputStream();
} else {
inputStream = httpURLConnection.getErrorStream();
}
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
return sb.toString().trim();
} catch (Exception e) {
Log.d(TAG, "InsertData: Error ", e);
errorString = e.toString();
return null;
}
}
}
private void showResult() {
try {
JSONObject jsonObject = new JSONObject(mJsonString);
JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
String brokenDate = item.getString(TAG_BROKEN_DATE);
String moldCode = item.getString(TAG_MOLD_CODE);
String finalHitting = item.getString(TAG_FINAL_HITTING_TIMES);
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put(TAG_BROKEN_DATE, brokenDate);
hashMap.put(TAG_MOLD_CODE, moldCode);
hashMap.put(TAG_FINAL_HITTING_TIMES, finalHitting);
mArrayList.add(hashMap);
}
ListAdapter adapter = new SimpleAdapter(
MoldBreakageHistoryActivity.this, mArrayList, R.layout.list_item_broken_mold,
new String[]{TAG_BROKEN_DATE, TAG_MOLD_CODE, TAG_FINAL_HITTING_TIMES},
new int[]{R.id.brokenDateListItem, R.id.brokenMoldListItem, R.id.finalHittingTimesListItem}
);
brokenMoldListView.setAdapter(adapter);
} catch (JSONException e) {
Log.d(TAG, "showResult : ", e);
}
}
Remove this:
mArrayList = new ArrayList<>();
GetData task = new GetData();
task.execute("http://www.cafe24.com/aaa.php");
from onCreate. onResume is executed right after onCreate and your async task was executing twice, that's why it was duplicated in the first place. When you hit the back only the onResume was executed, so the problem would happen then.
please just remove
mArrayList = new ArrayList<>();
GetData task = new GetData();
task.execute("http://www.cafe24.com/aaa.php");
From your onCreate method. but, if you need to do som scenario in onCreate and other one in onResume you can use mArrayList.clear(); before execute the new task only.
I have a Fragment in which I want to parse a JSON and create an ArrayList with some of its attributes and then put the ArrayList's data to a Spinner. However, I do not know if I am doing the AsyncTask as it I should.
Everytime I try a new way to parse the JSON from a URL in my Fragment Activity either the app crashes with "Unfortunately, the app has stopped" message or the Spinner stays empty. I verified with Logs that I never reach the onPostExecute() method on the AsyncTask.
Questions:
- What am I doing wrong?
- Should I be using AsyncTask?
My code:
private class LoadResources extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.v(TAG, "pre-execute");
}
// Call after onPreExecute method
#Override
protected String doInBackground(String... urls) {
Log.v(TAG, "background");
Log.v(TAG, urls[0]);
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
try {
URL u = new URL(urls[0]);
BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream(), Charset.forName("UTF-8")));
StringBuilder sb = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
// the above parsing works, I've tested
JsonParser parser = new JsonParser();
JsonElement elem = parser.parse(sb.toString());
JsonArray array = elem.getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
JsonElement elem1 = array.get(i);
JsonArray tmpArr = elem1.getAsJsonArray();
for (JsonElement elem2 : tmpArr) {
elem2.getAsJsonObject().getAsJsonPrimitive().getAsString());
myArrayList.add(elem2.getAsJsonObject().getAsJsonPrimitive("name").toString());
return urls[0];
}
protected void onPostExecute(String params) {
Log.v(TAG, params);
}
}
On the onCreateView:
LoadResources loader = new LoadResources();
loader.execute("http://localhost:5000/avalidpath);
text = (AutoCompleteTextView) rootView.findViewById(R.id.nomeAluno);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item, myArrayList);
text.setAdapter(adapter);
text.setThreshold(3);
Right now the app stops working when I swipe to this fragment.
Thanks in advance, guys.
Actually you should do the heavy work in doInBckground method.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter. Doc here
EDIT:
class LoadResources extends AsyncTask<String, Void, ArrayList<String>> {
Context context;
public LoadResources(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... urls) {
...
return myArrayList;
}
protected void onPostExecute(ArrayList<String> params) {
((YourActivity)context).setMyAdapter(params);
}
}
In your Activity (fragment or whatever) :
public void setMyAdapter(ArrayList<String> params) {
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item, myArrayList);
text.setAdapter(adapter);
}
onPostExecute is done on the UI thread. You have way too much work on it. Everything that isn't directly effecting a UI element should be done in doInBackground. Right now your doInBackground is doing nothing.
Move whole code from onPostExecute to doInBackground. You can use publishProgress(...); and onProgressUpdate to add items to list. Or create local list in AsyncTask and addAll items to your global List in onPostExecute
I'm using the AsyncTask to open a URL, access the server, fetch the content and display them in a list view in the main activity. The content extracted consists of a title of the newspaper and a URL to the website, which will be displayed on a WebView in a second activity, if a "read" button is clicked. I coded out the program straight away and it works, but when I looked back at it, I found something that seems unreasonable, so mainly I want to make clear how the code works. Here is the code for the main activity:
package com.example.newsapp;
public class MainActivity extends Activity {
static final private String LOG_TAG = "main";
private ArrayList<Content> aList;
private class Content{
Content() {};
public String title;
public String url;
}
private class MyAdapter extends ArrayAdapter<Content>{
int resource;
public MyAdapter(Context _context, int _resource, List<Content> titles) {
super(_context, _resource, titles);
resource = _resource;
// this.context = _context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout newView;
final Content content = getItem(position);
// Inflate a new view if necessary.
if (convertView == null) {
newView = new LinearLayout(getContext());
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(inflater);
vi.inflate(resource, newView, true);
} else {
newView = (LinearLayout) convertView;
}
// Fills in the view.
TextView tv = (TextView) newView.findViewById(R.id.listText);
ImageButton b = (ImageButton) newView.findViewById(R.id.listButton);
b.setBackgroundResource(0);
tv.setText(content.title);
Typeface type = Typeface.createFromAsset(getAssets(),"LiberationSerif-BoldItalic.ttf");
tv.setTypeface(type);
// Sets a listener for the button, and a tag for the button as well.
b.setTag(Integer.toString(position));
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Reacts to a button press.
Intent intent = new Intent(MainActivity.this, WebPage.class);
Bundle bundle = new Bundle();
bundle.putString("URL", content.url);
intent.putExtras(bundle);
startActivity(intent);
}
});
return newView;
}
}
class MyAsyncTask extends AsyncTask<String, String, String> {
private ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
InputStream inputStream = null;
String result = "";
Content content;
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Downloading the news...");
progressDialog.show();
progressDialog.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface arg0) {
MyAsyncTask.this.cancel(true);
}
});
}
#Override
protected String doInBackground(String... params) {
String url_select = params[0];
ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
try {
// Set up HTTP post
// HttpClient is more then less deprecated. Need to change to URLConnection
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
// Read content & Log
inputStream = httpEntity.getContent();
} catch (UnsupportedEncodingException e1) {
Log.e("UnsupportedEncodingException", e1.toString());
e1.printStackTrace();
} catch (ClientProtocolException e2) {
Log.e("ClientProtocolException", e2.toString());
e2.printStackTrace();
} catch (IllegalStateException e3) {
Log.e("IllegalStateException", e3.toString());
e3.printStackTrace();
} catch (IOException e4) {
Log.e("IOException", e4.toString());
e4.printStackTrace();
}
// Convert response to string using String Builder
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"), 8);
StringBuilder sBuilder = new StringBuilder();
String line = null;
while ((line = bReader.readLine()) != null) {
sBuilder.append(line + "\n");
}
inputStream.close();
result = sBuilder.toString();
} catch (Exception e) {
Log.e("StringBuilding & BufferedReader", "Error converting result " + e.toString());
}
return result;
} // protected Void doInBackground(String... params)
protected void onPostExecute(String result) {
//parse JSON data
try {
super.onPostExecute(result);
Log.i(LOG_TAG, result);
JSONObject object = new JSONObject(result);
JSONArray jArray = object.getJSONArray("sites");
for(int i=0; i < jArray.length(); i++) {
JSONObject jObject = jArray.getJSONObject(i);
content = new Content();
if (jObject.has("title") && jObject.has("url")){
content.title = jObject.getString("title");
content.url = jObject.getString("url");
aList.add(content);
aa.notifyDataSetChanged();
}
} // End Loop
progressDialog.dismiss();
} catch (JSONException e) {
// progressDialog.dismiss();
Log.e("JSONException", "Error: " + e.toString());
}
} // protected void onPostExecute(String result)
}
private MyAdapter aa;
private MyAsyncTask loadTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadTask = new MyAsyncTask();
loadTask.execute("http://luca-ucsc.appspot.com/jsonnews/default/news_sources.json");
aList = new ArrayList<Content>();
aa = new MyAdapter(this, R.layout.list_element, aList);
ListView myListView = (ListView) findViewById(R.id.listView1);
myListView.setAdapter(aa);
aa.notifyDataSetChanged();
}
public void refresh(View v){
if (loadTask.getStatus() == AsyncTask.Status.FINISHED){
aList.clear();
aa.notifyDataSetChanged();
new MyAsyncTask().execute("http://luca-ucsc.appspot.com/jsonnews/default/news_sources.json");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
So you can see that only after loadTask.execute() in onCreate(), do I create the object for alist and aa, but I'm already using them in onPostExecute() in the AsyncTaks class, so I'm not very clear what happens here, because onPostExecute() and the UI are on the same thread, so the code in onPostExecute() should be executed first.
I thought I should put
aList = new ArrayList<Content>();
aa = new MyAdapter(this, R.layout.list_element, aList);
into onPostExecute(), which is more logical to me, but the app crashes this way. Also I think deleting aa.notifyDataSetChanged(); in onPostExecute() shouldn't be a problem because it's also in the onCreate() method, but this actually causes the list view to be blank, without any content. Actually, putting any of the codes after loadTask.execute() into the if block of the onPostExecute() method causes some problem, or crashes the app. That would be great if somebody can give some insight or hint. Thanks for reading.
onPostExecute is called on the UI thread after the background task completes its work. You cannot guarantee the timing of this call in relation to other calls on the UI thread.
Since you are already implementing getView yourself, I recommend you extend BaseAdapter instead of ArrayAdapter and implement the other few required methods. It's not hard and you can use whatever data structure you want to back the adapter. Assuming you use a List<Content> to back the adapter, you can write a method to swap the list in place like so:
public void swapList(List<Content> newList) {
this.list = newList;
notifyDataSetChanged();
}
In your AsyncTask, you have complete control of the Params, Progress, and Result parameterized types. They don't all have to be String. You can do this instead:
private class myAsyncTask extends AsyncTask<String, Void, List<Content>> {
/* ... */
}
The String for Params is the URL (same as you do now). Void for Progress because you don't publish progress anyway. List<Content> for Result because that's the thing you actually want to end up with after doing your task.
You should do ALL of your work in doInBackground. There is no reason to deserialize a String into a JSONArray and mess around with that in onPostExecute, particularly since that is happening on the main thread. Rewrite doInBackground to return a List<Content>, and all you need in onPostExecute is this:
public void onPostExecute(List<Content> result) {
adapter.swapList(result);
}
Now you can create the adapter once (in onCreate()) and just swap the list whenever it's appropriate.
I want to fill a ListFragment with certain objects loaded from my MySql database.
It has to load the first 10 'objects' from my ResultSet.
I want to use an AsyncTaskLoader for this and put the loaded object in a ListItem each time I retreive it from the database.
Can anybody help me with this one? Tried searching for good examples or tutorials but I haven't really found something that's really useful...
Create your adapter with a new list in your preexecute method. Set that adapter to your listview.
Then in doInBackground read your database, create objects to fit in your list, but don't add them. Pas each object after made as parameter for your publishprogress method.
In onProgressUpdate add your object to the list and notify your adapter that the dataset is changed.
Below is an example for how I do it reading a twitter call.
private class parseTwitterTask extends AsyncTask<Void, TCListObject2, List<TCListObject2>> {
TCListObjectAdapter2 adapter;
List<TCListObject2> list;
#Override
protected void onPreExecute() {
list = new ArrayList<TCListObject2>();
ListView lv = (ListView)findViewById(R.id.twitterlist);
adapter = new TCListObjectAdapter2(list);
lv.setAdapter(adapter);
super.onPreExecute();
}
#Override
protected List<TCListObject2> doInBackground(Void... params) {
try {
String url = social.get("twittersearchurl");//"http://search.twitter.com/search.json?q=" + social.get("twitter");
String json = Internet.request(url, null);
JSONObject jo = new JSONObject(json);
if(jo.has("results")) {
JSONArray ar = jo.getJSONArray("results");
for(int i = 0; i < ar.length(); i++) {
TCListObject2 tweet = new TCListObject2();
JSONObject jobj = (JSONObject) ar.get(i);
tweet.id = "false";
tweet.img = jobj.getString("profile_image_url");
String text = jobj.getString("text");
text = Html.fromHtml(text).toString();
tweet.params.put(R.id.sub2, text);
String name = jobj.getString("from_user");
name = Html.fromHtml(name).toString();
tweet.params.put(R.id.text, name);
String time = jobj.getString("created_at");
tweet.params.put(R.id.sub1, Converter.timeToTimeAgo(time));
try {
tweet.time = new Date(time);
} catch(Exception e) {
e.printStackTrace();
}
tweet.celLayout = R.layout.cell_tweetobject;
publishProgress(tweet);
}
}
} catch(Exception e) {
e.printStackTrace();
}
return list;
}
#Override
protected void onProgressUpdate(TCListObject2... values) {
list.add(values[0]);
adapter.notifyDataSetChanged();
super.onProgressUpdate(values);
}
I was using AsyncTask to display data on a List, But the loading is visible, but it dosen't show the list..
public void getLocations(){
Connect client = new Connect(SERVICE_URI + "/GetLocations");
client.AddHeader("Accept", "application/json");
client.AddHeader("Content-Type", "application/json");
try {
client.Execute(RequestMethod.GET);
JSONObject rootJson = new JSONObject(client.getResponse());
JSONArray jsonArray = rootJson.getJSONArray("GetLocationsResult");
String[] names = null;
if (jsonArray != null) {
names = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
names[i] = json.getString("Name");
}
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, names));
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getLocations(){
Connect client = new Connect(SERVICE_URI + "/GetLocations");
client.AddHeader("Accept", "application/json");
client.AddHeader("Content-Type", "application/json");
try {
client.Execute(RequestMethod.GET);
JSONObject rootJson = new JSONObject(client.getResponse());
JSONArray jsonArray = rootJson.getJSONArray("GetLocationsResult");
String[] names = null;
if (jsonArray != null) {
names = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
names[i] = json.getString("Name");
}
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, names));
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
If data for ListAdapter is collected in doInBackground() of AsyncTask, Activity onCreate() does not wait for AsyncTask to complete.
So what we have:
1. Activity Start
2. AsyncTask start
3. Activity trying to set ListAdapter - it's empty, because AsyncTask does not completed
4. AsyncTask completed - but ListAdapter filled with empty data
My solution: AsyncTask should notify ListAdapter of Activity after data loading completes:
Public class MyActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myActivity);
ExpandableListView listView = (ExpandableListView) findViewById(R.id.expList);
//MyArrayList - data source for your list. For example, I use static ArrayList from other class. Replace with your data object.
final MyExpandableListAdapter adapter = new MyrExpandableListAdapter(getApplicationContext(), myArrayList);
listView.setAdapter(adapter);
int taskId=1; // type of task should be executed
MyAsyncTask myTask = new MyAsyncTask(taskId);
myTask.execute(adapter);
#Override
protected Dialog onCreateDialog(int id) {
ProgressDialog progress = null;
progress = new ProgressDialog(this);
//Should user work with app while data loading? In my case, no, so setCancelable=false
progress.setCancelable(false);
if (id==1) {
progress.setMessage("Getting locations, please wait...");
}
if (id==2) {
progress.setMessage("Task type #2 performing...");
}
return progress;
} // end onCreateDialog
class MyAsyncTask extends AsyncTask<Void, Void, Void> {
MyExpandableListAdapter adapter; //ExpandableListAdapter you wanna notify about data load completion
int taskId; //Type of tasks in your Activity. You have only one, however - getLocations().
MyAsyncTask(int taskId) {
//save task ID to use in doInBackground, showDialog and dismissDialog
this.taskId=taskId;
}
#Override
protected Void doInBackground(Void... params) {
if (taskId==1) {
// YOUR LONG-TIME TASK #1 THAT UPDATES DATA SOURCE FOR LIST ADAPTER GOES HERE;
}
if (taskId==2) {
// YOUR LONG-TIME TASK #2 THAT UPDATES DATA SOURCE FOR LIST ADAPTER GOES HERE;
// create more task types if needed
}
//this adapter will be used in onPostExecute() to notify Activity about data changes
adapter = (MyExpandableListAdapter) params[0];
return null;
}
#Override
protected void onPreExecute() {
//Show dialog for this task type. if need more than one - us switch here and in onCreateDialog,
// different dialog types for different tasks etc.
showDialog(taskId);
}
#Override
protected void onPostExecute(Void result) {
// IMPORTANT! Update data in Activity
adapter.notifyDataSetChanged();
dismissDialog(taskId);
}
} //end of AsyncTask
} //end of Activity class