Using Android ProgressDialog with AsyncTask and odd Activity Lifecycle - java

I couldn't think of a way to form my title to make my issue obvious, so here goes:
I'm a little over my head with diving into AsyncTask for the first time. I currently have an app that simply sends a tweet. To do this it must kick out to a WebView for Twitter authorization, which comes back to onNewIntent().
What I'm trying to do is throw up a simple Spinner ProgressDialog while it's connecting to the site/performing the AccessToken work, and then again while it's sending the tweet. I've only just discovered that I will need a new thread for the progress bar. Or rather, that I should be doing my "time-intensive work" in it's own separate thread to make using a ProgressDialog viable. My question is this: How can I have my progress spinner in the foreground while my authorization code works in the background, and eventually opens the WebView and comes back, and ultimately starts everything over at onResume()?
I'm sure I'm probably not doing everything else in the most proper fashion. I'm new to Android, but not to Java. I've put in my create- and dismissDialog(int) calls about where they should be, procedurally. As-is, everything otherwise works the way it should, but obviously my dialogs are simply not able show themselves.
I'm thinking I should basically put my entire authorize() and tweet() methods into their own AsyncTask. I'm just not sure how to go about that, especially since authorize() (or more specifically, loginToTwitter()) needs to end up saving the data it gets from the browser to shared preferences after it comes back to onNewIntent().
Thanks for any insights,
== Matt
public class IntegrateTwitter extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
mPrefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
mTwitter = new TwitterFactory().getInstance();
mTwitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
if(authorize()) {
tweet();
returnToMM();
}
}
private boolean authorize() {
Log.i(LOG_TAG, "Authorizing...");
showDialog(PD_AUTHORIZING);
boolean result = false;
if(responseExistsAndValid()) {
saveResponseToAccessToken();
}
if(isAuthorized()) {
Log.i(LOG_TAG, "Prefs have AccessToken, grabbing it...");
if(getAccessTokenFromPrefs()) {
Toast.makeText(IntegrateTwitter.this, "Authorized.", Toast.LENGTH_SHORT).show();
result = true;
}
}
else {
Log.i(LOG_TAG, "Prefs don't have AccessToken.");
if(!responseStringExists()) {
Log.i(LOG_TAG, "No response exists either, starting Twitter login process...");
Toast.makeText(IntegrateTwitter.this, "Authorizing...", Toast.LENGTH_SHORT).show();
// Here is where it kicks out to the browser for authentication
loginToTwitter();
}
else {
Toast.makeText(IntegrateTwitter.this, "Authorization failed.", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Response exists, so it must have failed once already, skipping Twitter login process.");
returnToMM();
}
}
deleteResponseFromPrefs();
dismissDialog(PD_AUTHORIZING);
return result;
}
private void tweet() {
showDialog(PD_TWEETING);
try {
Date testDate = new Date();
String testDateString = DateFormat.format("yyyy-MM-dd # hh:mm:ss", testDate.getTime()).toString();
mTwitter.updateStatus(testDateString + " Test Tweet");
Toast.makeText(this, "Tweet successful!", Toast.LENGTH_SHORT).show();
}
catch (TwitterException e) {
Toast.makeText(this, "Tweet error.", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, e.getMessage());
Log.i(LOG_TAG, Arrays.toString(e.getStackTrace()));
}
dismissDialog(PD_TWEETING);
}
// A bunch of support methods
// ...
}

Try this.....
I think you know that if we are not using AsyncTask, we can always use Thread along with Handler, to Post the work done on Non-UI thread to UI thread.
AsyncTask is provided by android to sync the UI and Non-UI work seamlessly.
I got this example by searching on Google, but changed it the way you wanted it to be.
Here it will Count till 50... and until it does it will keep displaying the ProgressDialog.
Please see the log while the program is executing to see the count increasing till 50.
public class AsyncTaskExampleActivity extends Activity
{
protected TextView _percentField;
protected Button _cancelButton;
protected InitTask _initTask;
ProgressDialog pd;
#Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate(savedInstanceState);
setContentView( R.layout.main );
_percentField = ( TextView ) findViewById( R.id.percent_field );
_cancelButton = ( Button ) findViewById( R.id.cancel_button );
_cancelButton.setOnClickListener( new CancelButtonListener() );
_initTask = new InitTask();
pd = ProgressDialog.show(AsyncTaskExampleActivity.this, "Loading", "Please Wait");
_initTask.execute( this );
}
protected class CancelButtonListener implements View.OnClickListener
{
public void onClick(View v) {
_initTask.cancel(true);
}
}
/**
* sub-class of AsyncTask
*/
protected class InitTask extends AsyncTask<Context, Integer, String>
{
// -- run intensive processes here
// -- notice that the datatype of the first param in the class definition matches the param passed to this method
// -- and that the datatype of the last param in the class definition matches the return type of this method
#Override
protected String doInBackground( Context... params )
{
//-- on every iteration
//-- runs a while loop that causes the thread to sleep for 50 milliseconds
//-- publishes the progress - calls the onProgressUpdate handler defined below
//-- and increments the counter variable i by one
int i = 0;
while( i <= 50 )
{
try{
Thread.sleep( 50 );
publishProgress( i );
i++;
} catch( Exception e ){
Log.i("makemachine", e.getMessage() );
}
}
pd.dismiss();
return "COMPLETE!";
}
// -- gets called just before thread begins
#Override
protected void onPreExecute()
{
Log.i( "makemachine", "onPreExecute()" );
super.onPreExecute();
}
// -- called from the publish progress
// -- notice that the datatype of the second param gets passed to this method
#Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
Log.i( "makemachine", "onProgressUpdate(): " + String.valueOf( values[0] ) );
_percentField.setText( ( values[0] * 2 ) + "%");
_percentField.setTextSize( values[0] );
}
// -- called if the cancel button is pressed
#Override
protected void onCancelled()
{
super.onCancelled();
Log.i( "makemachine", "onCancelled()" );
_percentField.setText( "Cancelled!" );
_percentField.setTextColor( 0xFFFF0000 );
}
// -- called as soon as doInBackground method completes
// -- notice that the third param gets passed to this method
#Override
protected void onPostExecute( String result )
{
super.onPostExecute(result);
Log.i( "makemachine", "onPostExecute(): " + result );
_percentField.setText( result );
_percentField.setTextColor( 0xFF69adea );
_cancelButton.setVisibility( View.INVISIBLE );
}
}
}

Related

android asynctask & progress dialog

I'm currently working on a android app in which I use asynctasks to carry out json rest request. I've got this working fine. I have also got a progress dialog being made visible on the preexecute then dismissing it on the postexecute all working fine. see code below.
#Override
protected void onPreExecute(){
Variables var = Variables.getInstance();
Variables.getInstance().showPd(ProgressDialog.show(Variables.getInstance().getContext(), var.getValue("loggingin_text"), var.getValue("pleasewait"), true, false));
}
protected void onPostExecute( JSONObject[] loginresponse ){
Variables.getInstance().dismisspd();
try {
JSONObject responseheader = loginresponse[0].getJSONObject("commonInputParameters");
if (responseheader.getString("status").equals("SUCCESS")) {
Variables.getInstance().setUsername( loginresponse[1].getString("username") );
Variables.getInstance().setSessiontoken(responseheader.getString("userSessionToken"));
delegate.onRequestCompletion( true );
} else {
delegate.onRequestCompletion(false);
}
}catch (JSONException je ) {
this.cancel( true );
}
}
final Button _loginBTN = ( Button ) findViewById(R.id.loginBTN );
_loginBTN.setText( vars.getValue( "loginbtn_text" ) );
_loginBTN.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Functions functions = Functions.getInstance();
if( functions.isNetworkAvailable(getApplicationContext())) {
if (functions.fullypopulated(new Object[]{_username, _password})) {
LoginRequest login = new LoginRequest(new responseInterface() {
#Override
public void onRequestCompletion(boolean successfulRequest) {
Variables.getInstance().dismisspd();
if ( !successfulRequest ) {
functions.showDialog(Variables.getInstance().getValue("login_err"), findViewById(R.id.input_username));
functions.clearEditText(new EditText[]{_username, _password});
functions.setError(new EditText[]{_username, _password});
} else {
Intent intent = new Intent(getApplicationContext(), NavigationHandler.class);
startActivity(intent);
finish();
}
}
#Override
public void onRequestCompletion(String requestResponse) {}
#Override
public void onRequestCompletion(int requestResponse) {}
#Override
public void onRequestCompletion(float requestResponse) {}
});
Map<String, String> loginDetails = new HashMap<String, String>();
loginDetails.put("username", _username.getText().toString());
loginDetails.put("password", _password.getText().toString());
login.execute(loginDetails);
} else {
functions.showDialog(Variables.getInstance().getValue("no_details"), findViewById(R.id.input_username));
functions.clearEditText(new EditText[]{_username, _password});
functions.setError(new EditText[]{_username, _password});
}
}
else {
functions.showDialog(Variables.getInstance().getValue("no_network"), findViewById(R.id.input_username));
}
}
});
The problem is that when I try to work in a time out into the async task the progress dialog shows but not until after it has completed and at which point I can't remove it.
This is how I'm trying to run it with a time out.
try{
login.execute(loginDetails).get( 5000, TimeUnit.MILLISECONDS );
}catch (InterruptedException ie ){
}catch (ExecutionException ee){
}catch (TimeoutException te ){
login.cancel(true);
}
Yes I know the catches are empty right now.
UPDATE:
Never mind looking at the get function again, it actually blocks the UI thread that is why the Progress Dialog isn't showing until the ASyncTask has completed. Is there anyway to implement a timeout feature?
Cancelling a task
A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns.
From http://developer.android.com/reference/android/os/AsyncTask.html
Mind the bold pieces ... as to my understanding, you should dismiss the Dialog in onCancelled() in case of Timeout.

How to wait for a function in the doBackground to return in android?

I have a asyc task that stores objects in cloudmine. Now I want to wait for the confirmation from cloudmine that the objects are stored. But before I get the conversation the postExecute method starts, which gives the wrong toast message. Main problem is that the cloudmine task itself is async and so I want doInBacground to wait for the cloudmine async to finish. Nothing I have tried has worked.
Here is the code:
public class createCloudmineLot extends AsyncTask<Void,Void,Boolean>
{
private boolean success;
private boolean inputFault;
protected void onPostExecute(Boolean arg0)
{
System.out.println("postExecute sucess value: " + success);
if(inputFault)
{
t = Toast.makeText(AddParking.this, "No Input!Please press enter after each input",Toast.LENGTH_LONG);
t.show();
}
else
if(arg0)
{
t = Toast.makeText(AddParking.this, "Parking Lot was added:" + success,Toast.LENGTH_LONG);
t.show();
}
else
{
t = Toast.makeText(AddParking.this, "Unable to add Parking Lot" + success,Toast.LENGTH_LONG);
t.show();
}
return;
}
#Override
protected Boolean doInBackground(Void... params)
{
// TODO Auto-generated method stub
CMApiCredentials.initialize(APP_ID, API_KEY, getApplicationContext());//initializing Cloudmine connetion
SimpleCMObject parkingLot = new SimpleCMObject();
if(name.equals("") | address.equals("") | pricing.equals("") | hours.equals("") | latitude.equals("") | longitude.equals(""))
{
inputFault = true;
return null;
}
parkingLot.add("name", name);
parkingLot.add("address",address);
parkingLot.add("pricing",pricing);
parkingLot.add("hours",hours);
double lat = Double.parseDouble(latitude);
double lon = Double.parseDouble(longitude);
CMGeoPoint locationCoordinates = new CMGeoPoint(lat,lon);
parkingLot.add("location",locationCoordinates);
parkingLot.save(new ObjectModificationResponseCallback()
{
public void onCompletion(ObjectModificationResponse response)
{
success = response.wasSuccess();
System.out.println("doInbackground: "+ success);
}
});
return success;
}//end of doBackground
}//end on AsyncTask
This is when I try with Broadcast Receivers. Using the receiver, nothing happens.
public class EditParking extends Activity
{
private ListView lotList;
private ArrayList<String> lots;
private ArrayAdapter<String> arrayAdpt;
private class ReceiveBroadcastActivity extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
System.out.println("received");
ArrayList<String> lots = intent.getStringArrayListExtra("ParkingLots");
ListView lotlist = (ListView)findViewById(R.id.lotList);
ArrayAdapter<String> arrayAdpt = new ArrayAdapter<String>(EditParking.this,android.R.layout.simple_list_item_1,lots);
lotList.setAdapter(arrayAdpt);
System.out.println("lots: "+ lots);
}
};
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.editparking_layout);
lotList = (ListView)findViewById(R.id.lotList);
lots = new ArrayList<String>();
lots.add("hello");
arrayAdpt = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,lots);
lotList.setAdapter(arrayAdpt);
arrayAdpt.setNotifyOnChange(true);
CMApiCredentials.initialize(APP_ID, API_KEY, getApplicationContext());//initializing Cloudmine connection
CMStore store = CMStore.getStore();
store.loadAllApplicationObjects(new CMObjectResponseCallback()
{
public void onCompletion(CMObjectResponse response)
{
for(CMObject object : response.getObjects())
{
// do something with each object
SimpleCMObject lot = (SimpleCMObject)object;
String lotInfo = lot.getString("name") + "\n" + lot.getString("address") +
"\nPrice: " + lot.getString("pricing") + "\nHours: " + lot.getString("hours");
System.out.println(lotInfo);
}
Intent broadcastIntent = new Intent();
lots.add("world");
broadcastIntent.putStringArrayListExtra("ParkingLots", lots);
broadcastIntent.setAction("com.cs275.findparking.broadcast");
sendBroadcast(broadcastIntent);
}
The problem is that the call you are doing inside the doInBackground is also an asynchronous call, you need to realize that by the time the execution thread reaches the end of doInBackground and returns an object, the onPostExecute will be called, so basically the problem in your case is that since your call is also asynchronous, its not blocking the thread and it moves inmediately to the end of the doInBackground method and the "callback" you receive from that call is executed way later than the whole asynctask did it's job, so, that said there's different ways to approach the issue.
1.- You could force the worker thread in doInBackground to wait for your callback to be executed(this requires a perfect understanding of java threads and the wait/notify methods)
2.- A simple approach would be, not to rely on onPostExecute method, and in stead send a Broadcast Receiver message from the callback method of your call, which will be handled in your activity whenever is done..
Regards!

ProgressDialog while loading data

I am encountering a problem in my Android application. I am creating a currency converter. I need to create a progressdialog that appears when you convert a value from one currency to another.
Here is part of my code:
if (text1.equals("US Dollar - USD") && text2.equals("Euro - EUR") && edittextdollars.length() > 0 && edittexteuros.length()==0) {
dialog1 = ProgressDialog.show(getActivity(), "", "Calculating...");
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try{
convertvalues("USD", "EUR");
handler.sendEmptyMessage(0);
}
catch (Exception e) {
edittexteuros.setText("Error");
}
}
});
thread.start();
}
private Handler handler = new Handler () {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
dialog1.dismiss();
break;
}
}
};
The progressdialog comes up and goes away, but nothing happens in the background. Here are a few pics of what my app looks like:
This is before the progressdialog comes.
When I press calculate:
After the progressdialog finishes:
As you can see, after the progressdialog goes away, my values don't convert.
In my code,
convertvalues("USD", "EUR");
just gets actual currency value from the internet and multiplies it with the value in my edittext. There is nothing wrong with it and it worked without the progressdialog. I have tested it many times myself.
What am I doing wrong here? I have checked Google for over a week, but I could not find a single solution. Any help regarding this problem is greatly appreciated.
Just like how you update your progressdialog in a handler, you must also update EditTexts in the handler (as it must run on the UI thread). So ideally you would return the result from convertvalues and then pass it to the handler via a message.
From what I can see, your code is fine but you aren't updating the TextView/EditText values when you dismiss the dialog. This means that although it looks like nothing is happening, it actually is - you just aren't updating to see the results.
So, assuming convertvalues() has the converted values stored somewhere, before you call dismiss() you should set your TextViews based on those values.
you can use asynctask in android
see following code may be it will help you..
private class asyncTask extends AsyncTask<Void, Void, Boolean>
{
Context context;
ProgressDialog pd;
asyncTask(Context context)
{
this.context = context;
pd = new ProgressDialog(activityContext);
}
protected void onPreExecute()
{
pd.setTitle("Loading..");
pd.setMessage("Please wait ...");
pd.setCancelable(false);
pd.show();
}
protected void onPostExecute(Boolean result)
{
if(pd.isShowing()) pd.dismiss();
}
#Override
protected Boolean doInBackground(Void... params)
{
convertvalues();
return boolean_value;
}
}
And Just Call this asynctask with
new asyncTask(Your_Context).execute();

Progress dialog while running computation task in background (AsyncTask)

I am very confused, i am trying for two days to make animation on an image while my engine is thinking of a move (this is a game app). I execute the chooseMove() method inside AsyncTask object because it is a little heavy recursive function that may take some time,and also i want to rotate an hourglass image while the engine is thinking. and i tried to do it every way i know: another AsyncTask, Android's own animation class,handlers etc'. but no matter what i do it seems that i can't make it work. if i try to execute two threads at the same time,it only executes one of them, and the same thing happens with android own animation class. so i tried to use a progress dialog just to see that i am not getting crazy,and guess what.. same problem! I show the progress dialog in the onPreExecute() ,but the doInBackgroun() never gets done! the progress dialog take control over the whole app for some reason. how should i do it? i though that the progress dialog is meant for this kind of things. thx!
EDIT: this is the code of my async task class. as you can see, i am showing a progress dialog in the onPreExecute() ,and dismissing it in the onPostExecute. but the onPost never gets called because the doInBackground() never gets called either.
protected void onPreExecute() {
super.onPreExecute();
activity.setPlaying(true);
if (android.os.Build.VERSION.SDK_INT >android.os.Build.VERSION_CODES.GINGERBREAD) {
// only for gingerbread and newer versions
activity.invalidateOptionsMenu();
}
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Thinking...");
progressDialog.setIndeterminate(true);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
}
#Override
protected Integer doInBackground(Void... arg0) {
int engineWin = board.takeWin(board.getBoard(), engine.getNumberOfEngine());
int opponentWin = board.takeWin(board.getBoard(), engine.getNumberOfOpponent());
if(engineWin!=-1){
try{
Thread.sleep(500);
}
catch(Exception e){}
return engineWin;
}
else if(opponentWin!=-1){
try{
Thread.sleep(500);
}
catch(Exception e){}
return opponentWin;
}
else{
if(engine.isEnginesTurn()&&!Board.checkGameOver(board.getBoard())){
int[] newBoard = new int[42];
System.arraycopy(board.getBoard(), 0, newBoard, 0, 42);
return engine.chooseMove(engine.isEnginesTurn(),newBoard,-500001,500001,0,4).getMove();
}
else{
return -1;
}
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
progressDialog.dismiss();
if(result!=-1){
ballAnimTask = new BallAnimTask(activity,boardView,board,engine);
ballAnimTask.execute(findSlotNumberByIndex(result));
}
}
this is the recursive chooseMove() i am calling in doInBackground(). before i tried to show the progress dialog,everything worked just fine. there is no problem with this function or any other function for that matter. only when i tried to do animations or dialogs at the same time,i got issues. the chooseMove() is physically on another class and i am only calling it from the AsyncTask. maybe this is the problem??
public Best chooseMove(boolean side,int[]board,int alpha,int beta,int depth,int maxDepth){
Best myBest = new Best();
Best reply;
int num;
if(Board.checkGameOver(board)||depth==maxDepth){
myBest.setScore(returnPositionScore(board));
return myBest;
}
if(side){
myBest.setScore(alpha);
num = numberOfEngine;
}
else{
myBest.setScore(beta);
num = numberOfOpponent;
}
ArrayList<Integer> availableMoves = new ArrayList<Integer>();
availableMoves = searchAvailableMoves(board);
for(int move:availableMoves){
board[move] = num;
reply = chooseMove(!side,board,alpha,beta,depth+1,maxDepth);
board[move] = 0;
if(side&&reply.getScore()>myBest.getScore()){
myBest.setMove(move);
myBest.setScore(reply.getScore());
alpha = reply.getScore();
}
else if(!side&&reply.getScore()<myBest.getScore()){
myBest.setMove(move);
myBest.setScore(reply.getScore());
beta = reply.getScore();
}
if(alpha>=beta){
return myBest;
}
}
return myBest;
}
If you want to perform any UI related operation from within an AsyncTask you need to call the AsyncTask publishProgress method. This will invoke an onProgressUpdate callback in the main UI thread and so you can then safely perform your UI related operations there.
Obviously any code in the onProgressUpdate can't block, though, since you are now back in the main UI thread. But you can update a status bar, for example, and then wait for the next onProgressUpdate callback before you update it again.
Just for some inspiration, here is the general code format that I have used successfully to show a horizontal progress bar which updates while a background task is running. I know it doesn't answer your exact question, but I hope it helps you to find your solution.
ProgressDialog myProgressDialog;
private void someFunctionThatStartsTheAsyncTask()
{
new myBackgroundTask.execute(someIntegerArgument);
}
private class myBackgroundTask extends AsyncTask<Integer, Integer, Boolean>
{
protected void onPreExecute()
{
myProgressDialog = new ProgressDialog(myContext);
myProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
myProgressDialog.setTitle("Doing something in background...");
myProgressDialog.setMessage("Please wait...");
myProgressDialog.setCancelable(false);
myProgressDialog.setIndeterminate(false);
myProgressDialog.setMax(100);
myProgressDialog.setProgress(0);
myProgressDialog.show();
}
protected Boolean doInBackground(Integer... params)
{
int someVariable = params[0];
boolean success;
for (whatever loop conditions)
{
// some long-running stuff, setting 'success' at some point
...
publishProgress(newPositionForProgressBar);
}
return success;
}
protected void onProgressUpdate(Integer... progressPosition)
{
myProgressDialog.setProgress(progressPosition[0]);
}
protected void onPostExecute(Boolean result)
{
myProgressDialog.dismiss();
if (result)
{
//doInBackground returned true
}
else
{
//doInBackground returned false
}
}
}

Parse.com Android API and Android Dialog

I have placed the parse method inside onCreate method. But my problem is how to show the Android Loading... Dialog??
Parse.initialize(this, "a", "b");
ParseQuery query = new ParseQuery("Category");
query.findInBackground(new FindCallback() {
#Override
public void done(List<ParseObject> catObjects, ParseException arg1) {
Log.d("Catlength", String.valueOf(catObjects.size()));
for(int i =0; i<catObjects.size(); i++){
Log.d("lengthName"+String.valueOf(i), String.valueOf(catObjects.get(i).getInt("Id")));
Category category = new Category();
category.Name= catObjects.get(i).getString("CatName");
category.id= catObjects.get(i).getInt("Id");
categories.add(category);
}
if(categories.size()>0){
setListAdapter(new CategoryArrayAdapter(CategoryListActivity.this, R.layout.row_category, categories));
}
else{
Toast.makeText(CategoryListActivity.this, "Our servers are busy. Hit refresh..", 3000).show();
}
}
});
Everything works fine in the above code but I couldn't figure out how to show the Dialog.
I'm unable to use AsycTask also as parse sdk invokes its own thread in the background and before the findInBackground execution finishes, the doInBackground completes the Asyc thread. That's why I invoked it in the main thread.
As the result I always get no results in my ArrayList.
Can someone please enlighten me.
I was in the same situation regarding the progress dialog, tried a few tricks and finally just declared a ProgressDialog class member:
protected ProgressDialog proDialog;
then created two methods:
protected void startLoading() {
proDialog = new ProgressDialog(this);
proDialog.setMessage("loading...");
proDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
proDialog.setCancelable(false);
proDialog.show();
}
protected void stopLoading() {
proDialog.dismiss();
proDialog = null;
}
and called startLoading() before the background operation and stopLoading()
inside the background operation after I got the the results.
startLoading();
ParseUser.logInInBackground(userName.getText().toString(), hashedPass, new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
Log.d(Constants.TAG, "User Loged in.");
ParseManager.sCurrentUser = user;
stopLoading();
finish();
} else {
stopLoading();
invalidCreds();
}
}
});
if you want to use AsyncTask don't call findInBackground() you can use find().
you can check it out in the api https://parse.com/docs/android/api/com/parse/ParseQuery.html#find()
hope this helps.
It's easy to get the progress of both uploads and downloads using ParseFile by passing a ProgressCallback to saveInBackground and getDataInBackground. For example:
byte[] data = "Working at Parse is great!".getBytes();
ParseFile file = new ParseFile("resume.txt", data);
file.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
// Handle success or failure here ...
}
}, new ProgressCallback() {
public void done(Integer percentDone) {
// Update your progress spinner here. percentDone will be between 0 and 100.
}
});

Categories