How to handle isCancelled in AsyncTask - android

I am trying to add this code to my doInBackGround so I can catch a flag that is being set when the user presses the back button
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
This my doInBackGround and the code I use to set the flag for the asynctask to be canceled
#Override
public void onBackPressed()
{
/** If user Pressed BackButton While Running Asynctask
this will close the ASynctask.
*/
if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED)
{
mTask.cancel(true);
}
super.onBackPressed();
finish();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
/** If Activity is Destroyed While Running Asynctask
this will close the ASynctask. */
if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED)
{
mTask.cancel(true);
}
super.onDestroy();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
if (pDialog != null)
{
if(pDialog.isShowing())
{
pDialog.dismiss();
}
super.onPause();
}
}
class LoadAllData extends AsyncTask<String, String, String> {
protected String doInBackground(String... args) {
try {
Intent in = getIntent();
String searchTerm = in.getStringExtra("TAG_SEARCH");
String query = URLEncoder.encode(searchTerm, "utf-8");
String URL = "example.com";
JSONParsser jParser = new JSONParsser();
JSONObject json = jParser.readJSONFeed(URL);
try {
JSONArray questions = json.getJSONObject("all").getJSONArray("questions");
for(int i = 0; i < questions.length(); i++) {
JSONObject question = questions.getJSONObject(i);
String Subject = question.getString(TAG_QUESTION_SUBJECT);
String ChosenAnswer = question.getString(TAG_QUESTION_CHOSENANSWER);
String Content = question.getString(TAG_QUESTION_CONTENT);
The problem comes when I try to translate isCancelled into my asynctask. I get an error under Downloader that says "Downloader cannot be resolved" I also get one under publishProgress that says "The method publishProgress(String...) in the type AsyncTask is not applicable for the argument (int)" I'm jus tasking is somebody can help put the isCancelled into my AsyncTask. I have also done my research and seen that there are more than one way to use isCancelled in your code. I have realized that dealing with isCancelled can really be a hassle for somebody new to it.

1) To resolve error one make Downloader a public static data variable of the class.
2) Please make sure
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long>
is the class declaration
After you called cancel() isCancelled() will return true, and after your doInBackground returned onCancelled is executed instead of onPostExecute. The Parameter will issue an interrupt on the background thread, so your long-time operations are closed. However, I'd assume you catch that somewhere?
Hope this Helps..:)..
If it doesnt solve the error..Please post logcat details
From SDK:
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. To ensure that a task is cancelled
as quickly as possible, you should always check the return value of
isCancelled() periodically from doInBackground(Object[]), if possible
(inside a loop for instance.)
Also please use super.onpause() etc at the begining of the function block
Refer this:- link

In this case you will need to write a separate file for your Asynctask class. also make an interface callback.
you do not need to overide the onBackPress button, you just need to set your progressDialog to cancelable(True) and set onCancelListner(). here you can set a flag isCanceld = true;
the whole scenario is defined in this link.
android asynctask sending callbacks to ui
see the answer of Dmitry Zaitsev try this one and let me know if stuck in any where
hope this helps

Related

make android AsynTask to wait for result

i want to implement a login activity. it checks user existance with a webservice.
EditText un=(EditText) findViewById(R.id.txtName);
EditText pass=(EditText) findViewById(R.id.txtPass);
WS ss=new WS();
String str=ss.execute("checkLogin",un.getText().toString(),pass.getText().toString()).get();
Intent in=new Intent(arg0.getContext(), Overview.class);
in.putExtra("username", str);
if(str=="No User")
Toast.makeText(getApplicationContext(), "ss", 300).show();
else
{
startActivity(in);
finish();
}
the problem is in "IF" section. "str" value sets after finishing code lines.
but i want to get "str" value then check for IF to run proper actions.
You need override onPostExecute method see below example
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
The whole point of an asynchronous task is to not block synchronously. You have several options if you do want synchronous behavior:
Don't use AsyncTask in the first place (probably not a good idea if it is a long-running network call)
Put the code you want to run after the AsyncTask completes it's background work in the onPostExecute method, which will have access to the result of the data returned from the background method
Provide a callback to the AsyncTask that onPostExecute can call when it is finished (similar in concept to the previous option but more formal and robust to changes)
I prefer the last option, but it also takes more dev time to write than the other options.
Don't forget that an AsyncTask may do it's background work and/or finish after the activity has been finished and shut down, so make sure to check for that state appropriately before you start interacting with the UI.
If you are trying to do a network call you shouldn't use asynctask rather use loopj or google's volley library .
Asynctask is not meant for long network calls , having said that here's an example of asynctask class , code:
class AsyncTaskExample extends AsyncTask<Void, Integer, String> {
private final String TAG = AsyncTaskExample.class.getName();
protected void onPreExecute(){
Log.d(TAG, "On preExceute...");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG, "On doInBackground...");
for(int i = 0; i<5; i++){
Integer in = new Integer(i);
publishProgress(i);
}
return "You are at PostExecute";}
protected void onProgressUpdate(Integer...a){
Log.d(TAG,"You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
Log.d(TAG,result);
}
}
Edit it as you wish and instanciate a new one in your code when you want to do the check up ,
Hope it helps

Android - Pause the for-loop till the AsyncTask Completed Successfully

The results object holds N number of JSON array value.The for-loop runs (initiate) the second array value before the first async task completed.I want to execute and move to the next array value,only after the current one gets finished successfully,If NOT wait for it to complete
if (results.length() > 0) {
for (int i = 0; i < results.length(); i++) {
JSONObject object = results
.getJSONObject(i);
FeedDataType item = new FeedDataType(
object);
AsyncTasks performBackgroundTask = new AsyncTasks();
performBackgroundTask.execute(item);
DBadapter.add(item);
Log.e("Aynsc Task",performBackgroundTask.getStatus().toString());
}
}
Log results shows only Pending (or) Running but Not Finished.
Give me a solution that doesn't affect the UI.
And,I don't want to use get() method on Asynctask class.
If you are using Asynck task try to override opPostExecute method.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
return null;
}
protected void onPostExecute(Long result) {
//This will call after doInBackground finished.
}
}
Write your code under onPostExecte method
The Async Task is been used as below
private class TaskBK extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
return null;
}
protected void onPostExecute(Long result) {
//This will call after the doInBackground method get completed.
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// This will get executed before doInBackground method get executed
}
}
Was facing the same problem. The thing is you cannot 'pause' the loop, instead what you can do give the loop a delay to give time for the async task to finish running.
Try arounf 3 seconds of delay. This is how to do it:
for (int i = 0; i < results.length(); i++) {
JSONObject object = results
.getJSONObject(i);
FeedDataType item = new FeedDataType(
object);
AsyncTasks performBackgroundTask = new AsyncTasks();
performBackgroundTask.execute(item);
DBadapter.add(item);
Log.e("Aynsc Task",performBackgroundTask.getStatus().toString());
Thread.sleep(3000);
}
The main Thread will sleep delay for three seconds allowing async task to finish execution an the loop will proceed after the delay. Give an upvote if you find this helpful.

How to cancel async task when doInBackground is calling another method of separate class

I am calling another class's method from doInBackground of async task.
Now i need to stop the download when cancel is called. I am not sure where to check the value of isCancelled().
class myasync extends Asynctask{
protected String doInBackground(String... sURL) {
abc = new abc();
abc.getURLResult(sURL[0])
}
}
class abc()
{
getURLResult(String URL)
{
for(int i=0; i<fp.size(); i++){
//some text to download
}
}
}
class myclass
{
myclass()
{
myasync = new myasync();
myasync.execute("http:\\");
}
stopDownload()
{
myasync.cancel(true);
}
}
EDIT:
Have used the below solution by combining the two answers below:
1. myclass.cancel1(true);
class myclass
{
myclass()
{
myasync = new myasync();
myasync.execute("http:\\");
}
stopDownload()
{
myasync.cancel1(true);
}
}
2.
class myasync extends Asynctask{
protected String doInBackground(String... sURL) {
abc = new abc();
abc.getURLResult(sURL[0])
}
cancel1()
{
abc.cancel();
}
}
3.
class abc()
{
private boolean cancel = false;
getURLResult(String URL)
{
for(int i=0; i<fp.size(); i++){
//some text to download
if(cancel)
break;
}
}
cancel()
{
cancel = true;
}
}
The above method is working. However the methods myclass.stopDownload() is running in UI thread , and hence myasync.cancel1() and abc.cancel() are running the UI thread. And myAsync.doInBackground() and hence abc.getURLResult() are running in seperate thread. I dont know much about inter process communication. I hope this is right thing to do.
Not very nice, but you can do something like this by adding a static variable isDownloading:
protected String doInBackground(String... sURL) {
abc = new abc();
abc.getURLResult(sURL[0])
}
}
class abc()
{
getURLResult(String URL)
{
for(int i=0; i<fp.size(); i++){
if(!myclass.isDownloading){ //ADDED
break; // or Return or handle Cancel
}
//some text to dopwnload
}
}
class myclass
{
public static boolean isDownloading; // ADDED
myclass()
{
myasync = new myasync();
isDownloading = true; // ADDED
myasync.execute("http:\\");
}
stopDownload()
{
isDownloading = false; // ADDED
myclass.cancel(true);
}
}
Update:
From the AsyncTask Cancel doc. we have to check if the async task got cancelled as you say.
Calling this method will result in onCancelled(Object) being invoked
on the UI thread after doInBackground(Object[]) returns. Calling this
method guarantees that onPostExecute(Object) is never invoked. After
invoking this method, you should check the value returned by
isCancelled() periodically from doInBackground(Object[]) to finish the
task as early as possible.
To do that send the asyncTask itself to the getURLResult as parameter along with the URL:
protected String doInBackground(String... sURL) {
new abc().getURLResult("http://...", this); // this here is the asyncTask itself.
}
getURLResult(String URL, myasync myAsyncTask)
{
for(int i=0; i<fp.size(); i++){
if(myAsyncTask.isCancelled()){
break;
}
}
}
Don't use a boolean as other suggested. it's not safe at all since another AsyncTask could be started. and it is a background threads. you can't guarantee which will check the boolean first. could cancel all AsyncTasks.
Old post:
The only place you need to check for cancellation to guarantee the cancellation! is on the onPostExecute. You can't guarantee that the async task got cancelled on calling cancel method. Therefore, you need to check whether the client application asked to cancel it and the returned data is not wanted anymore.
private boolean askedForCancellation = true;
#Override
protected void onPostExecute(Object response) {
if (!askedForCancellation)
// parse response
else
// ignore. or send message to activity to stop loading if you didn't already did that when called cancel method.
}
To achieve that add the following cancel method to the AsyncTask:
public final boolean cancel(boolean mayInterruptIfRunning) {
askedForCancellation = true;
return mFuture.cancel(mayInterruptIfRunning);
}
In your class:
myasync.cancel(true);
myasync = null;
Set myasync to null is ok. because, you can't use it anymore for execution again. you will get a runtime error. you need to re-initialise it.
To check if AsyncTask asked for cancellation. check if the value of
myasync is equal to null. remember the AsyncTask asked to get
cancelled and not cancelled because there is no guarantee that it is
going to be cancelled on calling cancel. What you do is to ignore the
response on onPostExecute
I used this approach in more than 15 applications till now. No bugs and no unexpected behaviours.

AsyncTask Cancel is not working

I am learning how to cancel asyncTask so there is no uses on the code below.
I tried to called the asyncTask and execute it then cancel it and execute it.
MyAsyncTask asyncTask = new MyAsyncTask();
Log.i("cancel","cancel 1");
asyncTask.execute();
Log.i("cancel","cancel 2");
asyncTask.onCancelled();
Log.i("cancel","cancel 3");
asyncTask.execute();
Log.i("cancel","cancel done");
"cancel 1" and "cancel 2" is executed finely as it shown on logcat but ActivityThread.performLaunchActivity error is thrown when "cancel 3" is trying to execute.
(cancel 3 is not showing on logcat) Anything wrong with my asyncTask code?
private class MyAsyncTask extends AsyncTask<String,Integer,Void>{
private ArrayList<Map<String, String>> list;
private ProgressBar progressBar;
#Override
protected Void doInBackground(String... arg0) {
progressBar = (ProgressBar)findViewById(R.id.year_expense_progressbar);
progressBar.setVisibility(View.VISIBLE);
getListView().setVisibility(View.GONE);
textView.setVisibility(View.GONE);
list = new ArrayList<Map<String, String>>();
String time = "";
String category = "";
String expense = "";
String day = "";
String month = "";
totalExpense = 0;
Cursor c = SQLLiteAdapter.fetchAllItems();
while(c.moveToNext() != false){
if(isCancelled()){
Log.e("cancel","cancel inside background");
break;
}
// if there is nothing is input, don't execute verifyLevel
if(tokenizedResult.isEmpty()) break;
category = c.getString(c.getColumnIndex(SQLLiteAdapter.col_category));
expense = c.getString(c.getColumnIndex(SQLLiteAdapter.col_price));
time = c.getString(c.getColumnIndex(SQLLiteAdapter.col_time));
day = c.getString(c.getColumnIndex(SQLLiteAdapter.col_day));
month = c.getString(c.getColumnIndex(SQLLiteAdapter.col_month));
VerifyLevel a = new VerifyLevel(tokenizedResult,category,expense,time,day,month);
if(!a.isEmpty()){
list.add(a.addToList());
}
totalExpense += a.totalExpense;
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
progressBar.setVisibility(View.GONE);
getListView().setVisibility(View.VISIBLE);
textView.setVisibility(View.VISIBLE);
fillData(list);
textView.setText("Total Expense is "+convertNumeric(totalExpense));
Log.i("yearExpense","buildList is finished");
}
#Override
protected void onCancelled(){
super.onCancelled();
list.clear();
progressBar.setVisibility(View.GONE);
totalExpense = 0;
Log.i("yearEx","Cancel asyncTask");
Toast.makeText(getApplicationContext(), "cancelled", Toast.LENGTH_SHORT).show();
}
}
My approach is slightly different and perhaps, a little lengthy. But it has always worked without any issues.
This piece of code goes in the doInBackground(). If you have a for... loop in it, then use the break; statement. If you do not use a for.... loop, remove it.
// CHECK IF THE USER HAS CANCELLED THE TASK
if (isCancelled()) {
cancelTask = true; // (OPTIONAL) THIS IS AN ADDITIONAL CHECK I HAVE USED. THINK OF IT AS A FAIL SAFE.
break; // REMOVE IF NOT USED IN A FOR LOOP
}
You already have an Asynctask declared: MyAsyncTask asyncTask = new MyAsyncTask();. Along with that, also create two instances of boolean. Call them, for example:
boolean blMyAsyncTask;
boolean cancelTask;
Now, in the onPreExecute(), toggle the status of the blMyAsyncTask instance:
blMyAsyncTask = true;
And in the onPostExecute():
blMyAsyncTask = false;
And, in the same onPostExecute(), I also do the remainder functions after checking the state of the cancelTask boolean. For example:
if (cancelTask == false) {
// THE NORMAL CODE YOU HAVE IN YOUR onPostExecute()
}
Finally, in the onDestroy() (I use this, but I suspect the onPause() could work too. Never done it in the onPause() in all honesty), check the status of the boolean blMyAsyncTask
if (blMyAsyncTask== true) {
asyncTask.cancel(true);
}
As I said at the start, it is lengthy, perhaps even complicated, but it has never failed. I also think of this as a little modular if you would. If I have more Asycntasks added to the Activity, I can add another check in the onDestroy().
you should not call asyncTask.onCancelled(); directly. You can call cancel(true) and inside your doInBackground() you check for isCancelled().
To cancel a AsyncTask call the below line.
asyncTask.cancel();
onCancelled() is a override method that is executed when ever cancel is called.
You can use either
asynctask.cancel(true);
or
asyncTask.wait();
"true " if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete

Android calling AsyncTask right after an another finished

I have some problem with Android AsyncTask. There is an Activity which contains some TextView a button and a picture. When an user entered this activity I start an asynctask to check whether the user can go toward from the activity (until the task not finish the button not active). Then I want to start another asyntask to get the picture.
So I made an inner class:
AsyncTask<String, Void, JSONObject>() authTask = new AsyncTask<String, Void, JSONObject>() {
#Override
protected JSONObject doInBackground(String... params) {
//call the rest api
}
#Override
protected void onPostExecute(JSONObject result) {
// check the result
// and make another asynctask
AsyncTask<String, Void, Bitmap> imageTask = new Async.... {
// get image
}
imageTask.execute();
}
}
and I call
authTask.execute(); from the UI thread.
I have a bad feeling about this, especially it seems doesn't work (it's ok few times but suddenly it "freeze": no exception just hanging and the progress bar is spinning. Nothing happens and the button won't be active.)
There is another way to get an information and when it's finished immediately start another task?
UDPATE:
I working with api level 10. In authTask I get some information which is needed to start imageTask (some id) so I have to call these tasks in a row. In api level 10 it's is possible?
Thanks in advance!
Br, Peter
you can use getStatus() checks whether the the AsyncTask is pending, running, or finished.and when finsh start your new task.like:
if(authTask .getStatus() == AsyncTask.Status.PENDING){
// My AsyncTask has not started yet
}
if(authTask .getStatus() == AsyncTask.Status.RUNNING){
// My AsyncTask is currently doing work in doInBackground()
}
if(authTask .getStatus() == AsyncTask.Status.FINISHED){
// START NEW TASK HERE
}
example for your app:
btn.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if (authTask != null && authTask.getStatus() == AsyncTask.Status.FINISHED) {
//START YOUR NEW TASK HERE
}
else
{
//IGNORE BUTTON CLICK
}
}
});
1:
You could write the code for authTask and then for imageTask, one after the other, within a single doInBackground(). This single AsyncTask instance would be fire by a single execute() statement. This may or may not be practical depending on needed UI interactions.
2:
Edit: as noted by kabuku this information is mostly for HoneyComb+. Pre HoneyComb I would definitely go with option 1 above. executeOnExecutor() is api level 11+
In receent versions, execute() will send your AsyncTasks in series by default (ICS+). If you want to make sure this happens, specify the serial executor.
In your case this would be:
authTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
// Image task will only be done AFTER textViewTask is done
imageTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
And for newer versions a simple
...
// ICS+ and pre honeycomb (I think)
authTask.execute();
// Image task will only be done AFTER textViewTask is done
imageTask.execute();
...
From the AsycnTask.execute() documentation:
Note: this function schedules the task on a queue for a single
background thread or pool of threads depending on the platform
version. When first introduced, AsyncTasks were executed serially on a
single background thread. Starting with DONUT, this was changed to a
pool of threads allowing multiple tasks to operate in parallel. After
HONEYCOMB, it is planned to change this back to a single thread to
avoid common application errors caused by parallel execution.
PS:
To run tasks independent of each other you must use the AsyncTask.THREAD_POOL_EXECUTOR. That requires a different executor:
// Go parallel! (NOT what you want)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Its not a good design to nest AsyncTask. Do all the heavy lifting in doInBackground and simply post/update the results. In other words, combine the processing of second AsyncTask in your first one.
From the code that you showed it does not seem to make sense to spawn second task. Just get you image inside doInBackground of the first task right after authorization.
If you need to update UI in between, you can do it in progress update.
int count;
private void attemptConnect()
{
count = 0;
str_lang = "English";
str_wait = "Plaese Wait";
new AllQuestion().execute();
}
private class AllQuestion extends AsyncTask<String, String, String> {
ProgressDialog pg;
#Override
protected void onPreExecute() {
super.onPreExecute();
pg = new ProgressDialog(LanguageActivity.this);
pg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pg.setMessage(str_wait);
pg.setCancelable(false);
pg.show();
}
#Override
protected String doInBackground(String... strings) {
try {
SoapObject soapObject = new SoapObject(AppConstant.NAMESPACE, AppConstant.QUESTION_SOAP_METHOD);
soapObject.addProperty("language", str_lang);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(soapObject);
HttpTransportSE se = new HttpTransportSE(AppConstant.webUrl);
se.call(AppConstant.QUESTION_SOAP_ACTION, envelope);
Object responce = envelope.getResponse();
Log.d("Question List:=>>", "" + responce);
return responce.toString();
} catch (Exception e) {
e.printStackTrace();
pg.dismiss();
return null;
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (pg.isShowing()) {
pg.dismiss();
Log.i(TAG, s);
if (s != null || !s.equalsIgnoreCase("")) {
try {
JSONArray array = new JSONArray(s);
for (int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
String queId = obj.getString(TAG_QID);
String que = obj.getString(TAG_QUE);
String str_Opt = obj.getString(TAG_OPT);
question = new Question(queId, que, str_lang, str_catId, str_Opt, manager.getDateTime());
helper.insertQuestion(question);
}
count++;
if (count < 5) {
if (count == 1) {
str_lang = "German";
str_wait = "bitte warte einen Moment";
new AllQuestion().execute();
}
if (count == 2) {
str_lang = "Italian";
str_wait = "per favore aspetta un momento";
new AllQuestion().execute();
}
if (count == 3) {
str_lang = "Chinese";
str_wait = "请稍候";
new AllQuestion().execute();
}
if (count == 4) {
str_lang = "French";
str_wait = "patientez s'il-vous-plait";
new AllQuestion().execute();
}
Log.d("All Question:-", question.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
I have an idea to make async series in just one async task:
protected Boolean doInBackground(String... params) {
if(params[0] == "taskA") {
//do somthing
params[0] = "taskB";
}
if(params[0] == "taskB") {
//do somthing
params[0] = "taskC";
}
if(params[0] == "taskC") {
//do somthing
params[0] = "taskD";
}
if(params[0] == "taskD") {
//do somthing
return true;
}
And in your main thread just call async task like this:
ShowMyProgress(); //if you like
new MyAsyncTask().execute("taskA");
And finally you can hide your progress on onPostExecute like:
protected void onPostExecute(final Boolean success) {
if (success) {
....
HideMyProgress();
}
}
I have solved this kind of problem when i had to download something from a database before login in the user into the app, with this i fixed this problem.
To use ObservableInteger you can do this
first declare it
private ObservableInteger mObsInt;
then in your onCreate you will have a listener waiting for the values of the mObsInt to change, after those values change you can do anything you want
//Listener
mObsInt = new ObservableInteger();
mObsInt.set(0);
mObsInt.setOnIntegerChangeListener(new OnIntegerChangeListener()
{
#Override
public void onIntegerChanged(int newValue)
{
if (mObsInt.get()==1)
//Do something if the first asyncTask finishes
if (mObsInt.get()==2){
//Do something if the second asyncTask finishes, in this case i just go to another activity when both asyncTasks finish
Intent mainIntent = new Intent().setClass(LoginActivity.this, Principal.class);
startActivity(mainIntent);
finish();
}
}
});
So, how it works
ObservableInteger will be looking for changes in the variable mObsInt, so lets say if mObsInt is equal to 1 it will do something, if is equal to 2 will do another thing, so, to solve this problem with 2 asynctasks is easy, when one of the asynctasks finishes mObsInt will be equal to 1 , if the other asyncTask finishes so mObsInt will be mObsInt++ , and then your mObsInt will be equal to 2, the listener will be waiting for the values, and then do what you want to do when the values match your if statment at the onCreate method
now, just in your asynctasks just put in your onPostExecute() method this line
mObsInt.set(mObsInt.get()+1);
so if the first async finish, mObsint == 1 , if the second finish mObsInt == 2, and then you handle what you want to do in your onCreate method
hope this helps for you, it helped me
You can get more info at this doc : https://developer.android.com/reference/android/databinding/ObservableInt.html
happy coding !

Categories

Resources