I have a list in my app that is populated via a http request to our database API. Then it parses the JSONArray that is returned, and sets the list appropriately. By the way I am quite new to Java coding and the eclipse environment.
I have achieved the http request with the custom library developed by loopj (located here)
However, when I go to the list in my app, it freezes for a second or two (while it collects the data) and then populates this list and everything works fine. Is it possible to implement a loader that will display until the list has completed loading with the current AsyncHttpClient I am using? Or do I need to change to a different one. I can't provide any code due to contractual agreements.
Thanks for any suggestions!
I do something like this in my Async class
public class Async extends AsyncTask {
private ProgressDialog dialog;
public Context applicationContext;
#Override
protected void onPreExecute() {
//this should appear like a loading bar
this.dialog = ProgressDialog.show(applicationContext, "Calling",
"Update List ...", true);
}
#Override
protected Object doInBackground(Object... params) {
//call your method and threat response
return SyncActivity.getUpdatedList();
}
#Override
protected void onPostExecute(Object result) {
this.dialog.cancel();
}
}
Related
I have a button, and when I clicked on it, I load other Activity, onCreate of this I call a method that fills a spinner with data from a Web Service.
Well, When I click at this button the screen stay "frozen" and then shows the Activity. So, I thought that it could be a good thing shows a progress dialog for user, and after gets the return of the Web Service, ends the progress dialog.
I tried use Handler, and now I'm trying to use AsyncTask, but, geting NullPointerException, because my program is filling spinner before web service get called.
private void fillSpinner(){
//runWebService();
new CallWebServiceAsyncTask().execute(null);
mAdapter = new PlanesAdapter(this, allPlanes);
mList.setAdapter(mAdapter);
}
class CallWebServiceAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(PlanesActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
#Override
protected Void doInBackground(Void... v) {
runWebService();
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
because my program is filling spinner before web service get called.
you should fill data after getting data in onPostExecute Method
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
mAdapter = new PlanesAdapter(this, allPlanes);
mList.setAdapter(mAdapter);
}
What #SamirMangroliya suggested is correct but you even need to know where you are going wrong. When you call an AsyncTask you are asking the application to do some actions in the background which will take place in the non-UI thread. Now when you call execute() on your AsyncTask object the application code written in the function doInBackground(Void... v) runs in background and your control returns to the next statement following the call to execute() [new CallWebServiceAsyncTask().execute(null)], which in your case is the action of filling the adapter values. These values are yet to be received from the webservice. The only place where you can be sure that your background action is completed is the function onPostExecute(Void result) where as suggested you can create your adapter.
I have four Tab at the top of my apps
The content of the fourth tab is that it will get data from sql server and then display in listview
since the amount of data retrieved is quite big, it takes 2-3 sec
The problem is that:
After I click the fourth tab, it has no response, then after 2-3sec, it displays the content
As I know it is loading the data from database, I will not continue to click
However, when users click it and no response, he may click and click and click
How to show something to user so that they know it is loading data??
You should use a CrusorLoader. This will display a loading circle while still making the UI active. Note that even if you're using lower versions of the android API, you can still access the CursorLoader class via the Android Support Package. For more information on loaders, checkout
new SomeTask(0).execute(); // write this line in your 4th tab onCreate()
/** Inner class for implementing progress bar before fetching data **/
private class SomeTask extends AsyncTask<Void, Void, Integer>
{
private ProgressDialog Dialog = new ProgressDialog(yourActivityClass.this);
#Override
protected void onPreExecute()
{
Dialog.setMessage("loading...");
Dialog.show();
}
#Override
protected Integer doInBackground(Void... params)
{
//Task for doing something
// get data from sql server and then display in listview
return 0;
}
#Override
protected void onPostExecute(Integer result)
{
if(result==0)
{
//do some thing if your list completed
}
// after completed finished the progressbar
Dialog.dismiss();
}
}
When a long-running process is started, you'll want to indicate that something is happening so the user knows to wait. You want a progress dialog.
Here is an example:
http://www.androidpeople.com/android-progress-dialog-example
I am using a TabActivity with 4 separate Activities - one for each tab.
One of the Activities is a ListView that has a custom ArrayAdapter.
The issue is that when I press the Tab to change to this view, the Activity loads the content in before the view changes, this appears as though nothing happens for a couple of seconds until the xml is loaded and parsed etc.
I have looked for an example but this is my first Android appllication and I am having difficulty in understanding the flow.
Can anyone point me to some code that will allow me to instantly change the view (I can inform user content is loading) while loading the content in the background thread
thank you
EDIT - I am porting code over from an existing iOS app - I wasn't able to better articulate the problem as I didn't realise how the UI thread could be blocked in this situation, and due to the complexity of the existing code and deadline I didn't want to change the structure too much.
I narrowed down the issue before I saw your code Jennifer but it is the solution I used so Ill mark yours as right.
here is what I used if it helps anyone else, I had to put the function I called to trigger the data load onto a background thread and then display the content when that thread had done its work
This class was declared within my
public class TableView extends ListActivity
Which was hard for me to get my head around having not done this before ;)
public class GetContentTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog pdialog;
#Override
protected void onPreExecute(){
super.onPreExecute();
pdialog = new ProgressDialog(TableView.this);
pdialog.setTitle(progressDialogTitle);
pdialog.setMessage(progressDialogMessage);
pdialog.show();
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
setUpAndLoadList(); // the function to display the list and fill it with content
pdialog.dismiss();
}
#Override
protected Void doInBackground(Void... params) {
doInitialLoad(); // The function to load any xml data from server
return null;
}
}
You can use a progress Dialog (can inform user content is loading)
ProgressDialog dialog;
private class XMLOperation extends AsyncTask<String, Void, String> {
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
System.out.println("onPreExecute");
dialog= ProgressDialog.show(mContext, "", "Loading Content....");
dialog.setCancelable(false);
}
#Override
protected String doInBackground(String... urls) {
//do your Background task
}
protected void onPostExecute(String result) { //dismiss dialog
try {
if(dialog.isShowing()){
dialog.dismiss();
}
} catch (Exception exception) {
dialog.dismiss();
}
}
Use AsyncTask, or (possibly) a separate thread.
http://developer.android.com/reference/android/os/AsyncTask.html
I would also throw in my 2 cents and say don't use TabActivity. Just have your own buttons that look like tabs, but that's not really critical to this topic.
I recently discovered that since my app is pulling so much data from a few URLs, it takes about 3-7 seconds for it to load the main layout. So, I made a layout called 'loading' to display, which is just simply a TextView that states "Please wait while data is being collected...". However, when I run my app, it won't display the 'loading' layout. It simply goes black for a while, like it used to before, and then go to the main layout. I tried cleaning the project too, and it still does this. Here's a portion of my Main.java:
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.loading);
populateArray();
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Set up click listeners for all buttons
View v1 = findViewById(R.id.continueButton);
v1.setOnClickListener(this);
View v2 = findViewById(R.id.colorCheck);
v2.setOnClickListener(this);
View v3 = findViewById(R.id.terms);
v3.setOnClickListener(this);
}
populateArray(); is the method that is pulling all the information of the internet. So, I figured, "Why not tell it to set the content view immediately to 'loading', have it run populateArray();, then display the main layout?" Obviously, I must be missing something here. Any ideas?
==========================================================================
EDIT: I tried using AsyncTask, but I'm getting a force close. I'm also getting a warning saying the AsyncTask class is never used. Here's my code:
P.S. ProgressDialog dialog; is a global definition.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dialog = ProgressDialog.show(this, "",
"Please wait while data is collected...", true);
// Set up click listeners for all buttons
View v1 = findViewById(R.id.continueButton);
v1.setOnClickListener(this);
View v2 = findViewById(R.id.colorCheck);
v2.setOnClickListener(this);
View v3 = findViewById(R.id.terms);
v3.setOnClickListener(this);
}
And...
private class LoadData extends AsyncTask <String[][], String, String> {
#Override
protected String doInBackground(String[][]... voidThisArray) {
String voidThisString = null;
populateArray();
return voidThisString;
}
#Override
protected void onPostExecute(String voidThisString) {
setContentView(R.layout.main);
dialog.dismiss();
}
}
I would give you the LogCat for the force close but for some reason the LogCat isn't displaying anything...
You want to use an AsyncTask to first: create a ProgressDialog that will display the loading message. Then the AsyncTask will work in the background collecting all of the data.
Hope that helps.
private class Task extends AsyncTask<Void,Integer, Void> {
private ProgressDialog dia;
#Override protected void onPreExecute() {
dia = new ProgressDialog(MyContext.this);
dia.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dia.setMessage("Loading. Please wait...");
dia.setCancelable(false);
dia.show();
// Set up preserver download stuff
}
#Override protected Void doInBackground(Void... voids) {
// perform server download stuff
}
#Override public void onProgressUpdate(Integer... prog) {
if (prog == null)
return;
dia.setProgress(prog[0]);
}
#Override protected void onPostExecute(Void voids) {
// Do any post op stuff
dia.cancel();
}
}
You should see this page for information about threading. Basically if your application is going to do any long running operation, you want it in a thread. Your UI is locking up because your performing this operation on your UI thread.
As far as progress updates, I personally use a ProgressDialog to show when something is happening, although you could build a custom view to indicate this.
Look at AsyncTask and execute
populateArray();
in doInBackground method of AsyncTask.
And call
setContentView
only once you can show loading by using onPreExecute and onPostExecute method of AsyncTask
I am using AsyncTask on button click to refresh the screen. Following is the sequence of events that happen on btn click
progress dialog shows up
The doInBackground is called and thread is initialized which calls a web service. The web service fetches/uploads data. A pass/fail flag is set once the web service is called.
My problem is the onPostExecute is never called and therefore the screen is never refreshed.
And secondly by the time the data is downloaded and the web service sets the flag my code has already hit return stmt in doInBackground.
Question is how do i stop execution in my asynctask so that the web service is done downloading/uploading the data and finally execute onPostexecute.
FYI
I also get the following warning in eclipse
The method onPostExecute(boolean) from
the type
Screen.ConnectWebService is
never used locally
private class ConnectWebService extends AsyncTask <Void, Void, Boolean>
{
private final ProgressDialog pd = new ProgressDialog(screen.this);
protected void onPreExecute() {
pd.show(Screen.this, "Sync", "Sync in progress",true,false);
}
protected Boolean doInBackground(Void... unused) {
if (SyncInProgress == false)
{
CallWSThread();//creates thread which calls web service
}
Log.d("doInBackground","doInBackground");
return SyncStatus;
}
protected Void onPostExecute(boolean result)
{
pd.dismiss();
if (result==true) drawRadioButtons();
return null;
}
}
It should be:
protected Void onPostExecute(Boolean result)
As djg noted, you have a typo in your method declaration. You can avoid these kinds of mistakes by using the annotation #Override when you're implementing methods from a super class.