Im new to Android Development. I want to fill spinner by Json array which load from the Http request(by AsyncTask). My AsyncTask in seperate class called Load_spinnrs. I to do this?
here is my http request
try{
String DataSendingTo="http://www.mysite.com/AppRequest/load_data";
//HttpClient
HttpClient httpClient = new DefaultHttpClient();
//Post header
HttpPost httpPost = new HttpPost(DataSendingTo);
//Adding data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("authorized","001"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
JSONTokener tokener = new JSONTokener(builder.toString());
JSONArray finalResult = new JSONArray(tokener);
//How to load Spinner ?????
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
After you get array of JSON
You have to do like:
final String[] items = new String[jsonArray.length()];
// looping through All Contacts
for(int i = 0; i < jsonArray.length(); i++){
JSONObject c = jsonArray.getJSONObject(i);
// Storing each json item in variable
String name = c.getString(TAG_NAME);
items[i]=c.getString(TAG_NAME);
System.out.println("Hello events "+items);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp.setAdapter(adapter);
Populate an Android Spinner with JSON data from a RESTful web API
If you are extending AsyncTask in separate class then you will need to pass Activity context from which you are executing extending for accessing UI elements in on normal java class. for this you can use Load_spinnrs class constructor to get Activity context and use onPostExecute for accessing Spinner as:
class Load_spinnrs extends AsyncTask<String,String,String>{
Activity activity;
Context context;
public Load_spinnrs(Activity activity,Context context){
this.activity=activity;
this.context=context;
}
...
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
//access UI elements here..
Spinner mySpinner = (Spinner)activity.findViewById(R.id.my_spinner);
adapter = new ArrayAdapter<String> (context,
android.R.layout.simple_spinner_item, items);
//....
super.onPostExecute(result);
}
}
For pass Context start AsyncTask as from Activity:
Load_spinnrs load_spin=new Load_spinnrs(this,this);
load_spin.execute(parameters);
for easily understand, Load your Load_spinnrs class as, sub class of your main class.
for example;
public class Main_Class extends Activity
{
private Spinner spinner;
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.userprofiles);
//init spinner here
}
private class Load_spinnrs extends AsyncTask<Void, Void, String>{
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(Void... params) {
// your http request
}
#Override
protected void onPostExecute(String result) {
//update spinner here.
}
}
Here is the implementation in the AsyncTask to show the loading spinner and then dismiss it when the AsyncTask is complete.
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
<put code here>
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
}
}
}
Look at this may be help you:
GetServerData.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Server Request URL
String serverURL = "http://androidexample.com/media/webservice/getPage.php";
// Create Object and call AsyncTask execute Method
new LongOperation().execute(serverURL);
}
});
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//UI Element
uiUpdate.setText("Output : ");
Dialog.setMessage("Downloading source..");
Dialog.show();
}
for more details you have :
http://androidexample.com/AsyncroTask_Example_To_Get_Server_Data_-_Android_Example/index.php?view=article_discription&aid=59&aaid=84
http://www.androidhive.info/2013/12/android-populating-spinner-data-from-mysql-database/
Best regards
Related
Hi i need to save json data in sqlite. But iam getting following error.
Can't create handler inside thread that has not called
Looper.prepare().
This is my code. It is shwoing database open/database created...
/**
* Async task class to get json by making HTTP call
* */
private class GetDetails extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#SuppressLint("NewApi")
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Create an array to populate the spinner
branchlist = new ArrayList<String>();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
// System.out.println("response"+jsonStr);
if (jsonStr != null) {
try {
// jsonString is a string variable that holds the JSON
JSONArray itemArray=new JSONArray(jsonStr);
for (int i = 0; i < itemArray.length(); i++) {
value=itemArray.getString(i);
Log.e("json", i+"="+value);
dbhelper=new DataBaseHepler(getApplicationContext());
sqLiteDatabase=dbhelper.getWritableDatabase();
dbhelper.addinnformation(value,sqLiteDatabase);
Toast.makeText(getBaseContext(),"Data saved",Toast.LENGTH_LONG).show();
dbhelper.close();
branchlist.add(itemArray.getString(i));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
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
* */
ArrayAdapter<String> stringadapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
branchlist);
spinner1.setAdapter(stringadapter);
// spinner1
// .setAdapter(new ArrayAdapter<String>(MainActivity.this,
// android.R.layout.simple_spinner_dropdown_item,
// branchlist));
}
}
This error is due to Toast inside doInBackground(Void... arg0) method:
Toast.makeText(getBaseContext(),"Data saved",Toast.LENGTH_LONG).show();
Clearly the Android OS wont let threads other than the main thread change UI elements. Follow this link for more details on this: https://dzone.com/articles/android-%E2%80%93-multithreading-ui
I am seeking help so that I may get an ArrayList<String> in an alternate class. As you can see in the following code I have inner and outer classes. Both work as expected and I am both able to insert values and fetch details from my online database using php scripts (I have commented out these details for code clarity as it was taking up a lot of space).
public class ServerRequests {
ProgressDialog progressDialog;
public static final int CONNECTION_TIMEOUT = 15000;
public static final String SERVER_ADDRESS = "// my url domain";
public ArrayList<String> list1 = new ArrayList<>();
public ServerRequests(Context context)
{
progressDialog = new ProgressDialog(context);
progressDialog.setCancelable(false);
progressDialog.setTitle("Processing");
progressDialog.setMessage("Please wait..");
}
public void storeDataInBackground(MultiChallenge multiChallenge)
{
progressDialog.show();
new StoreDataAsyncTask(multiChallenge).execute();
}
public class StoreDataAsyncTask extends AsyncTask<Void , Void , Void>
{
MultiChallenge multiChallenge;
public StoreDataAsyncTask(MultiChallenge multiChallenge)
{
this.multiChallenge = multiChallenge;
}
#Override
protected Void doInBackground(Void... voids) {
// where I insert values...
#Override
protected void onPostExecute(Void aVoid) {
progressDialog.dismiss();
super.onPostExecute(aVoid);
Log.d("ServerRequests", "Post execute");
}
}
public ArrayList<String> fetchDataInBackground() {
progressDialog.show();
new FetchDataAsyncTask().execute();
return list1;
}
public class FetchDataAsyncTask extends AsyncTask<Void, Void, ArrayList<String>>
{
public FetchDataAsyncTask()
{
}
String text = "";
#Override
protected ArrayList<String> doInBackground(Void... params) {
InputStream is1;
HttpParams httpRequestParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpRequestParams, CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpRequestParams, CONNECTION_TIMEOUT);
HttpClient client = new DefaultHttpClient(httpRequestParams);
HttpPost post = new HttpPost(// my url domain+ "// php script");
try {
HttpResponse httpResponse = client.execute(post);
is1 = httpResponse.getEntity().getContent();
BufferedReader reader;
reader = new BufferedReader(new InputStreamReader(is1, "iso-8859-1"), 8);
String line = null;
while ((line = reader.readLine()) != null) {
text += line + "\n";
}
is1.close();
JSONArray data = new JSONArray(text);
for (int i = 0; i < data.length(); i++) {
Log.d("GetNames", data.getString(i));
JSONObject jsonData = data.getJSONObject(i);
list1.add( // I successfully add details to list1 here, I have commented it out for code clarity);
}
for (int iterate = 0; iterate < list1.size(); iterate++) {
Log.d("list1", list1.get(iterate));
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
// catch (JSONException e) {e.printStackTrace();}
return list1;
}
#Override
protected void onPostExecute(ArrayList<String> myList) {
progressDialog.dismiss();
super.onPostExecute(myList);
}
}
}
Now that I successfully add to the list1 (I can tell values are added to it because of the for loop with the int iterate), I now need to send it to another class whereby I will put items in a listview. This is my code in the class in which I want to display the details of the ArrayList I get from ServerRequests:
ServerRequests serverRequests = new ServerRequests(DisplayInfo.this);
ArrayList<String> myList = new ArrayList<>();
myList = serverRequests.fetchDataInBackground();
for (int iterate = 0; iterate < myList.size(); iterate++) {
Log.d("Display", myList.get(iterate));
However the above for loop is never called, indicating that myList is never given the details that list1 manages to get in the doInBackground method of class FetchDataAsync.
Please note I did spend a number of hours attempting a variety of my own ideas and answers derived from SO before asking this question. Thank you all in advance of your help.
In the onPostExecute method call a function in the calling class
#Override
protected void onPostExecute(ArrayList<String> myList) {
progressDialog.dismiss();
super.onPostExecute(myList);
MainActivity.sendStrings(myList);
}
In the calling function implement a method:
public static void sendStrings(ArrayList<String> strings)
{
//Add for loop here
}
Alternatively you can also use interfaces. Call the interface in onPostExecute and implement the interface in the calling class
I have a list fragment. When I run the app, I see an empty listView.
I don't know what the problem is. Maybe I should use a library?
public class MyEmployeFragment extends ListFragment {
private static final String ATTRIBUTE_ID = "p_id";
private static final String ATTRIBUTE_NAME = "p_name";
private static final String ATTRIBUTE_LAST_NAME = "p_last_name";
ArrayList<spr_item> ret_data;
MyTask task;
SimpleAdapter sAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
task = new MyTask();
task.execute();
return inflater.inflate(R.layout.my_employe, null);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ret_data = new ArrayList<spr_item>();
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
ret_data.size());
Map<String, Object> m;
for (int i = 0; i < ret_data.size(); i++) {
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_ID, ret_data.get(i).getId());
m.put(ATTRIBUTE_NAME, ret_data.get(i).getName());
m.put(ATTRIBUTE_LAST_NAME, ret_data.get(i).getLastName());
data.add(m);
}
// массив имен атрибутов, из которых будут читаться данные
String[] from = {ATTRIBUTE_ID, ATTRIBUTE_NAME, ATTRIBUTE_LAST_NAME};
// массив ID View-компонентов, в которые будут вставлять данные
int[] to = {R.id.tw_employe_id, R.id.tw_employe_name, R.id.tw_employe_last_name};
// создаем адаптер
sAdapter = new SimpleAdapter(getActivity(), data, R.layout.list_item_employee,
from, to);
// определяем список и присваиваем ему адаптер
ListView lvSimple = (ListView) getView().findViewById(android.R.id.list);
lvSimple.setAdapter(sAdapter);
}
class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
String s = "5ACACEC6-752B-4EFF-AA50-EEBE58A52113";
// String user_guid = myPrefs.getString("guid", "");
HttpActivity _http = new HttpActivity("192.168.10.11", "80");
_http.set_addr_protocol("/WebSite/P/spr/spr.aspx/");
_http.add_param("query", "spr_employee_get");
// _http.add_param("p_guid", user_guid.toString().trim());
_http.add_param("p_guid", s);
_http.send();
List<spr_item> tempList = _http.getArrayParamValue();
for(int i = 0; i < tempList.size(); i++)
ret_data.add(tempList.get(i));
//employer_name = _http.getArrayParamValue("p_name");
//employer_id = _http.getArrayParamValue("p_id");
//employer_last_name = _http.getArrayParamValue("p_last_name");
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
sAdapter.notifyDataSetChanged();
}
}
}
With the above code apart from the Empty list you may have the null pointer exception too if the task is too quick to load. Here onCreate is called first onCreateView next and onActvityCreated next. So it is better to initialise adapter in onCreate set the adapter to listView in onCreateView and set listView listeners in onActvityCreated using getListView() method.
Apart from this if you are using local database to retrieve data you need to use cursorADapter to fetch the data
The adapter's data references (ArrayList, array, etc.), tend to get lost pretty easily. In that case the notfiyDataSetChanged() method will not work. If you are adamant on using this method I suggest you check the references to the adapter's source again. If that is not the case this is the approach I've used in my project. A small warning in advance, the formatting and the closing of brackets is poorly executed, but the approach is still clear enough.
public class MyFragment extends ListFragment {
// For populating the list view.
SomeAdapter adapter;
public MyFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] parameters = {"url for request"};
new GetRequestTask().execute(parameters);
}
// The async task to make the HTTP GET requests.
class GetRequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e("GetRequestTask", "Client protocol exception.");
e.printStackTrace();
} catch (IOException e) {
Log.e("GetRequestTask", "IO exception.");
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Update UI with the new response.
new UpdateUITask().execute(result);
}
}
}
// The async task to update the UI.
class UpdateUITask extends AsyncTask<String, String, ArrayList<Something>>{
#Override
protected ArrayList<Something> doInBackground(String... input) {
ArrayList<Something> someArray = new ArrayList<Something>();
try{
// Do some JSON magic to parse the data.
}
catch(JSONException je){
Log.e("UpdateUITask", "JSON parsing error occured.");
je.printStackTrace();
}
return someArray;
}
#Override
protected void onPostExecute(ArrayList<Something> result) {
super.onPostExecute(result);
Log.i("UpdateUITask", "Updating UI.");
adapter = new SomeAdapter(getActivity(), R.layout.some_list_item, restOfTheParameters);
setListAdapter(adapter);
}
}
}
}
I have two asynctask in one class and i am having trouble in executing them at the same time.
Here is my scenario, my the user clicks the view january calendar button it will show up the events for the month of calendar and the comments for it. The events and comments are stored in mysql database so i have to fetch different url. I used asyctask to fetch the url. Whenever i call the other asynctask it cannot be resolved. help me out!
Here is my code:
package sscr.stag;
#SuppressLint("ShowToast")
public class Calendar extends ListActivity {
// All xml labels
TextView txtEvent;
// Progress Dialog
private ProgressDialog pDialog;
JSONArray user;
JSONObject hay;
private static final String CALENDAR_URL = "http://www.stagconnect.com/StagConnect/calendar/januaryCalendar.php";
private static final String COMMENT_URL = "http://www.stagconnect.com/StagConnect/calendar/januaryReadComment.php";
private static final String TAG_USER = "username";
private static final String TAG_MESSAGE = "message";
private static final String TAG_TIME = "time";
private static final String TAG_ARRAY = "posts";
private JSONArray mCalendar = null;
private ArrayList<HashMap<String, String>> mCommentList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendaradmin);
txtEvent = (TextView) findViewById(R.id.event);
new LoadCalendar().execute();
new LoadCommentCal().execute(); // error here, says cannot be resolved in this type
}
private class LoadCalendar extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Calendar.this);
pDialog.setMessage("Loading Calendar.. ");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
String json = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(CALENDAR_URL);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
json = EntityUtils.toString(resEntity);
Log.i("Profile JSON: ", json.toString());
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
#Override
protected void onPostExecute(String json) {
super.onPostExecute(json);
pDialog.dismiss();
try
{
hay = new JSONObject(json);
JSONArray user = hay.getJSONArray("posts");
JSONObject jb= user.getJSONObject(0);
String event = jb.getString("activities");
txtEvent.setText(event);
}catch(Exception e)
{
e.printStackTrace();
}
}
public void updateJSONdata() {
mCommentList = new ArrayList<HashMap<String, String>>();
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(COMMENT_URL);
try {
mCalendar = json.getJSONArray(TAG_ARRAY);
for (int i = 0; i < mCalendar.length(); i++) {
JSONObject c = mCalendar.getJSONObject(i);
String username = c.getString(TAG_USER);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_USER, username);
mCommentList.add(0, map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void updateList() {
ListAdapter adapter = new SimpleAdapter(Calendar.this, mCommentList,
R.layout.calendar_comment, new String[] { TAG_MESSAGE,
TAG_USER, TAG_TIME }, new int[] { R.id.message,
R.id.username, R.id.time });
setListAdapter(adapter);
ListView lv = getListView();
lv.scrollTo(0, 0);
}
public class LoadCommentCal extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Calendar.this);
pDialog.setMessage("Loading Comments...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(Void... args) {
updateJSONdata();
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pDialog.dismiss();
updateList();
}
}
}
}
Your second asynctask public class LoadCommentCal extends AsyncTask is inside the first asynctask!
You need to move it out of the first asynctask.
private class LoadCalendar extends AsyncTask<String, String, String> {
...
}
... other functions
private class LoadCommentCal extends AsyncTask<Void, Void, String> {
...
}
You are declaring lots of things inside the first AsyncTask I strongly reccomend to close your AsyncTask after the onPostExecute
#Override
protected void onPostExecute(String json) {
super.onPostExecute(json);
pDialog.dismiss();
try
{
hay = new JSONObject(json);
JSONArray user = hay.getJSONArray("posts");
JSONObject jb= user.getJSONObject(0);
String event = jb.getString("activities");
txtEvent.setText(event);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
and then removing one } at the end of the java file (and also reindent if you wish)
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