AsyncTask and error handling on Android - android

I'm converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What's unclear to me is how to handle exceptions if something goes haywire in AsyncTask#doInBackground.
The way I do it is to have an error Handler and send messages to it. It works fine, but is it the "right" approach or is there better alternative?
Also I understand that if I define the error Handler as an Activity field, it should execute in the UI thread. However, sometimes (very unpredictably) I will get an Exception saying that code triggered from Handler#handleMessage is executing on the wrong thread. Should I initialize error Handler in Activity#onCreate instead? Placing runOnUiThread into Handler#handleMessage seems redundant but it executes very reliably.

It works fine but is it the "right"
approach and is there better
alternative?
I hold onto the Throwable or Exception in the AsyncTask instance itself and then do something with it in onPostExecute(), so my error handling has the option of displaying a dialog on-screen.

Create an AsyncResult object ( which you can also use in other projects)
public class AsyncTaskResult<T> {
private T result;
private Exception error;
public T getResult() {
return result;
}
public Exception getError() {
return error;
}
public AsyncTaskResult(T result) {
super();
this.result = result;
}
public AsyncTaskResult(Exception error) {
super();
this.error = error;
}
}
Return this object from your AsyncTask doInBackground methods and check it in the postExecute. ( You can use this class as a base class for your other async tasks )
Below is a mockup of a task that gets a JSON response from the web server.
AsyncTask<Object,String,AsyncTaskResult<JSONObject>> jsonLoader = new AsyncTask<Object, String, AsyncTaskResult<JSONObject>>() {
#Override
protected AsyncTaskResult<JSONObject> doInBackground(
Object... params) {
try {
// get your JSONObject from the server
return new AsyncTaskResult<JSONObject>(your json object);
} catch ( Exception anyError) {
return new AsyncTaskResult<JSONObject>(anyError);
}
}
protected void onPostExecute(AsyncTaskResult<JSONObject> result) {
if ( result.getError() != null ) {
// error handling here
} else if ( isCancelled()) {
// cancel handling here
} else {
JSONObject realResult = result.getResult();
// result handling here
}
};
}

When I feel the need to handle Exceptions in AsyncTask properly, I use this as super class:
public abstract class ExceptionAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private Exception exception=null;
private Params[] params;
#Override
final protected Result doInBackground(Params... params) {
try {
this.params = params;
return doInBackground();
}
catch (Exception e) {
exception = e;
return null;
}
}
abstract protected Result doInBackground() throws Exception;
#Override
final protected void onPostExecute(Result result) {
super.onPostExecute(result);
onPostExecute(exception, result);
}
abstract protected void onPostExecute(Exception exception, Result result);
public Params[] getParams() {
return params;
}
}
As normal, you override doInBackground in your subclass to do background work, happily throwing Exceptions where needed. You are then forced to implement onPostExecute (because it's abstract) and this gently reminds you to handle all types of Exception, which are passed as parameter. In most cases, Exceptions lead to some type of ui output, so onPostExecute is a perfect place to do that.

If you want to use the RoboGuice framework which brings you other benefits you can try the RoboAsyncTask which has an extra Callback onException(). Works real good and I use it.
http://code.google.com/p/roboguice/wiki/RoboAsyncTask

I made my own AsyncTask subclass with an interface that defines callbacks for success and failure. So if an exception is thrown in your AsyncTask, the onFailure function gets passed the exception, otherwise the onSuccess callback gets passed your result. Why android doesn't have something better available is beyond me.
public class SafeAsyncTask<inBackgroundType, progressType, resultType>
extends AsyncTask<inBackgroundType, progressType, resultType> {
protected Exception cancelledForEx = null;
protected SafeAsyncTaskInterface callbackInterface;
public interface SafeAsyncTaskInterface <cbInBackgroundType, cbResultType> {
public Object backgroundTask(cbInBackgroundType[] params) throws Exception;
public void onCancel(cbResultType result);
public void onFailure(Exception ex);
public void onSuccess(cbResultType result);
}
#Override
protected void onPreExecute() {
this.callbackInterface = (SafeAsyncTaskInterface) this;
}
#Override
protected resultType doInBackground(inBackgroundType... params) {
try {
return (resultType) this.callbackInterface.backgroundTask(params);
} catch (Exception ex) {
this.cancelledForEx = ex;
this.cancel(false);
return null;
}
}
#Override
protected void onCancelled(resultType result) {
if(this.cancelledForEx != null) {
this.callbackInterface.onFailure(this.cancelledForEx);
} else {
this.callbackInterface.onCancel(result);
}
}
#Override
protected void onPostExecute(resultType result) {
this.callbackInterface.onSuccess(result);
}
}

A more comprehensive solution to Cagatay Kalan's solution is shown below:
AsyncTaskResult
public class AsyncTaskResult<T>
{
private T result;
private Exception error;
public T getResult()
{
return result;
}
public Exception getError()
{
return error;
}
public AsyncTaskResult(T result)
{
super();
this.result = result;
}
public AsyncTaskResult(Exception error) {
super();
this.error = error;
}
}
ExceptionHandlingAsyncTask
public abstract class ExceptionHandlingAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, AsyncTaskResult<Result>>
{
private Context context;
public ExceptionHandlingAsyncTask(Context context)
{
this.context = context;
}
public Context getContext()
{
return context;
}
#Override
protected AsyncTaskResult<Result> doInBackground(Params... params)
{
try
{
return new AsyncTaskResult<Result>(doInBackground2(params));
}
catch (Exception e)
{
return new AsyncTaskResult<Result>(e);
}
}
#Override
protected void onPostExecute(AsyncTaskResult<Result> result)
{
if (result.getError() != null)
{
onPostException(result.getError());
}
else
{
onPostExecute2(result.getResult());
}
super.onPostExecute(result);
}
protected abstract Result doInBackground2(Params... params);
protected abstract void onPostExecute2(Result result);
protected void onPostException(Exception exception)
{
new AlertDialog.Builder(context).setTitle(R.string.dialog_title_generic_error).setMessage(exception.getMessage())
.setIcon(android.R.drawable.ic_dialog_alert).setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
//Nothing to do
}
}).show();
}
}
Example Task
public class ExampleTask extends ExceptionHandlingAsyncTask<String, Void, Result>
{
private ProgressDialog dialog;
public ExampleTask(Context ctx)
{
super(ctx);
dialog = new ProgressDialog(ctx);
}
#Override
protected void onPreExecute()
{
dialog.setMessage(getResources().getString(R.string.dialog_logging_in));
dialog.show();
}
#Override
protected Result doInBackground2(String... params)
{
return new Result();
}
#Override
protected void onPostExecute2(Result result)
{
if (dialog.isShowing())
dialog.dismiss();
//handle result
}
#Override
protected void onPostException(Exception exception)
{
if (dialog.isShowing())
dialog.dismiss();
super.onPostException(exception);
}
}

This simple class can help you
public abstract class ExceptionAsyncTask<Param, Progress, Result, Except extends Throwable> extends AsyncTask<Param, Progress, Result> {
private Except thrown;
#SuppressWarnings("unchecked")
#Override
/**
* Do not override this method, override doInBackgroundWithException instead
*/
protected Result doInBackground(Param... params) {
Result res = null;
try {
res = doInBackgroundWithException(params);
} catch (Throwable e) {
thrown = (Except) e;
}
return res;
}
protected abstract Result doInBackgroundWithException(Param... params) throws Except;
#Override
/**
* Don not override this method, override void onPostExecute(Result result, Except exception) instead
*/
protected void onPostExecute(Result result) {
onPostExecute(result, thrown);
super.onPostExecute(result);
}
protected abstract void onPostExecute(Result result, Except exception);
}

Another way that doesn't depend on variable member sharing is to use cancel.
This is from android docs:
public final boolean cancel (boolean mayInterruptIfRunning)
Attempts to cancel execution of this task. This
attempt will fail if the task has already completed, already been
cancelled, or could not be cancelled for some other reason. If
successful, and this task has not started when cancel is called, this
task should never run. If the task has already started, then the
mayInterruptIfRunning parameter determines whether the thread
executing this task should be interrupted in an attempt to stop the
task.
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.
So you can call cancel in catch statement and be sure that onPostExcute is never called, but instead onCancelled is invoked on UI thread. So you can show the error message.

Actually, AsyncTask use FutureTask & Executor, FutureTask support exception-chain
First let's define a helper class
public static class AsyncFutureTask<T> extends FutureTask<T> {
public AsyncFutureTask(#NonNull Callable<T> callable) {
super(callable);
}
public AsyncFutureTask<T> execute(#NonNull Executor executor) {
executor.execute(this);
return this;
}
public AsyncFutureTask<T> execute() {
return execute(AsyncTask.THREAD_POOL_EXECUTOR);
}
#Override
protected void done() {
super.done();
//work done, complete or abort or any exception happen
}
}
Second, let's use
try {
Log.d(TAG, new AsyncFutureTask<String>(new Callable<String>() {
#Override
public String call() throws Exception {
//throw Exception in worker thread
throw new Exception("TEST");
}
}).execute().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
//catch the exception throw by worker thread in main thread
e.printStackTrace();
}
or use FutureTask directly like below
FutureTask<?> futureTask = new FutureTask(() -> {throw new RuntimeException("Exception in TaskRunnable");}) {
#Override
protected void done() {
super.done();
//do something
Log.d(TAG,"FutureTask done");
}
};
AsyncTask.THREAD_POOL_EXECUTOR.execute(futureTask);
try {
futureTask.get();
} catch (ExecutionException | InterruptedException e) {
Log.d(TAG, "Detect exception in futureTask", e);
}
logcat as below

Personally, I will use this approach.
You can just catch the exceptions and print out the stack trace if you need the info.
make your task in background return a boolean value.
it's like this:
#Override
protected Boolean doInBackground(String... params) {
return readXmlFromWeb(params[0]);
}
#Override
protected void onPostExecute(Boolean result) {
if(result){
// no error
}
else{
// error handling
}
}

Another possibility would be to use Object as return type, and in onPostExecute() check for the object type. It is short.
class MyAsyncTask extends AsyncTask<MyInObject, Void, Object> {
#Override
protected AsyncTaskResult<JSONObject> doInBackground(MyInObject... myInObjects) {
try {
MyOutObject result;
// ... do something that produces the result
return result;
} catch (Exception e) {
return e;
}
}
protected void onPostExecute(AsyncTaskResult<JSONObject> outcome) {
if (outcome instanceof MyOutObject) {
MyOutObject result = (MyOutObject) outcome;
// use the result
} else if (outcome instanceof Exception) {
Exception e = (Exception) outcome;
// show error message
} else throw new IllegalStateException();
}
}

If you know the correct exception then you can call the
Exception e = null;
publishProgress(int ...);
eg:
#Override
protected Object doInBackground(final String... params) {
// TODO Auto-generated method stub
try {
return mClient.call(params[0], params[1]);
} catch(final XMLRPCException e) {
// TODO Auto-generated catch block
this.e = e;
publishProgress(0);
return null;
}
}
and go to "onProgressUpdate" and do the folowing
#Override
protected void onProgressUpdate(final Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
mDialog.dismiss();
OptionPane.showMessage(mActivity, "Connection error", e.getMessage());
}
This will be helpful in some cases only. Also you can keep a Global Exception variable and access the exception.

Related

doInBackground is not getting called sometimes Android

In my application, there are multiple asynctasks. Please let me know why doInBackground of an asynctask sometimes does not getting called. Its onPreExecute method gets called. Is there any issue because of multiple asynctasks or something else?
/* ASync class for test table */
public class TestAsynch extends AsyncTask<String, Void, String>{
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
String result1=API_Manager.getInstance().sendTestData(userName);
try {
if(result1 != null) {
// save in db
}
}
}
catch( Exception e) {
e.printStackTrace();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}
If your project has multiple asynctasks you must check that there is a limit of asynctasks that can be executed. When you create a new AsyncTask it will be added on a Pool and will be execute only when is possible.
Check this answer:
Multitasking on android
And the docs: ThreadPoolExecutor
Here is an example on how properly handle multiple AsyncTasks AsyncTaskManager
OnPreExecute() gets called on the UI thread and doInBackground() is called on the background thread.
There is one dedicated background thread for the async task. This behaviour can be changed if you want to.
http://android-er.blogspot.in/2014/04/run-multi-asynctask-as-same-time.html
Now, say you have multiple instances of async task and I'm assuming you are calling execute() to run the async tasks. This will trigger all the preExecute immediately since UI thread is free but for the doInBackground it will triggered one by one. Hence it may take some time for the next async task to start.
doInBackground should run on a loop using a Boolean to check before execution. Before your Task is being executed, set a global boolean (may be true/false) depends on which you prefer and values add on thread should call runOnUiThread.
startExect = true;
new TestAsynch().execute();
then change this
public class TestAsynch extends AsyncTask<String, Void, String>{
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
String result1=API_Manager.getInstance().sendTestData(userName);
try {
if(result1 != null) {
// save in db
}
}
}
catch( Exception e) {
e.printStackTrace();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}
to this
public class TestAsynch extends AsyncTask<String, Void, String> {
String result1 = null;
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
result1=API_Manager.getInstance().sendTestData(userName);
while (startExecute) {
Thread exe = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5);
}
catch( Exception e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
if(result1 != null) {
// save in db
}
}
});
}
}); exe.start();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}

Android: AsyncTask behaving weird in onCreate

I'm executing the practically identical code (besides the return statement) in onCreate() in two different ways:
once in a Thread (that works)
and once in an AsyncTask
Somehow the Exception thrown in the AsyncTask can't even be debugged... do you have an idea why this code doesn't work in the AsyncTask and why I can't debug de Exception? (It is not present as a variable)
public class TrainingProgressActivity extends ActivityTemplate {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_training_progress);
// the not working AsyncTask variant
new ProgressGetterTask().execute("");
// the working Thread variant
new Thread(new Runnable() {
public void run() {
try {
RestTemplate restTemplate = RestTemplateFactory.createRestTemplate();
FeatureSetCollectionProgress i = restTemplate.postForObject(URLHelper.BASE_PATH+"training/progress", getDevice(), FeatureSetCollectionProgress.class);
System.out.println(i.getMobilityProgress().get(0).getTransportationMeanType().toString());
} catch(Exception e) {
System.out.println("ex");
e.printStackTrace();
}
}}).start();
}
/**
* ProgressGetterTask. (not working ???)
*/
private class ProgressGetterTask extends AsyncTask<String, FeatureSetCollectionProgress, FeatureSetCollectionProgress> {
protected FeatureSetCollectionProgress doInBackground(String... urls) {
try {
RestTemplate restTemplate = RestTemplateFactory.createRestTemplate();
return restTemplate.postForObject(URLHelper.BASE_PATH+"training/progress", getDevice(), FeatureSetCollectionProgress.class);
} catch(Exception e) {
e.printStackTrace();
return null; // setting breakpoint here, 'e' cannot be resolved to a variable.
}
}
protected void onPostExecute(FeatureSetCollectionProgress featureSetCollectionProgress) {
if(featureSetCollectionProgress!=null) {
} else {
}
}
}
}

Can't get async task to work

I was calling a class which was performing network operations on the main thread, causing my app to blow up on more recent devices. So I've tried moving the call to the class into a AsyncTask inner class in my main activity. However now i'm getting null reference expections.
Here's my AsyncTask:
private class RetreiveAmazonNodesXML extends AsyncTask {
private Exception exception;
#Override
protected Object doInBackground(Object... params) {
try {
childrenBrowseNodesXml = new Amazon(browseNodeId, locality);
} catch (Exception e) {
this.exception = e;
}
return null;
}
}
And here's where I call it in my activity:
RetreiveAmazonNodesXML test = new RetreiveAmazonNodesXML();
test.execute();
parseXmlFile(childrenBrowseNodesXml.getBrowseNodesXML());
childrenBrowseNodesXml isn't getting updated and returning null. I know my Amazon class works fine so its something im doing with AsyncTask, but I have no idea?
Use callback for get result from async task. Here interface callback class:
public interface Callback {
public void onSuccess(Object data);
public void onError(String errorMsg);
}
And create instance this class and implement its:
final Callback resCallback = new Callback() {
#Override
public void onSuccess(Object data) {
parseXmlFile(data);
}
#Override
public void onError(String errorMsg) {
//show error with Alert or Toast
}
};
And create asynctask class with your callback:
RetreiveAmazonNodesXML test = new RetreiveAmazonNodesXML(resCallback);
test.execute(yourObjectsParams);
Write asynctask class like this:
private class RetreiveAmazonNodesXML extends AsyncTask {
private Callback responderCallback;
private Exception exception;
public GeneralHttpTask(Callback callback){
this.responderCallback = callback;
}
#Override
protected Object doInBackground(Object... params) {
try {
Amazon childrenBrowseNodesXml = new Amazon(browseNodeId, locality);
return childrenBrowseNodesXml;
} catch (Exception e) {
this.exception = e;
}
return null;
}
#Override
protected void onPostExecute(Object result) {
if(result != null) {
responderCallback.onSuccess(result);
} else {
responderCallback.onError(exception);
}
}
}
It is because you're trying to use the value that AsyncTask hasn't returned, as AsyncTask is running asyncronously.
You should put parseXmlFile(childrenBrowseNodesXml.getBrowseNodesXML()); into your AsyncTask's onPostExecute() method, like this:
private class RetreiveAmazonNodesXML extends AsyncTask {
private Exception exception;
#Override
protected Object doInBackground(Object... params) {
try {
childrenBrowseNodesXml = new Amazon(browseNodeId, locality);
} catch (Exception e) {
this.exception = e;
}
return null;
}
#Override
protected void onPostExecute(Object obj) {
parseXmlFile(childrenBrowseNodesXml.getBrowseNodesXML());
}
}
Also, return null in doInBackground method may not be a good manner, the stuff that doInBackground returns will be passed as a parameter to onPostExecute() method automatically by AsyncTask.
For more about the AsyncTask, please refer to the Android Developers: AsyncTask
The problem is, that you create a background thread (AsyncTask) that fills the childrenBrowseNodesXml after a while (when it's actually executed), but you try to use it immediately in your activity code.
Move your parseXMLFile to onPostExecute(Void result) method of AsyncTask instead.

Catch Exception of AsyncTask. Need Thinking

I want to catch exception of a thread in doInBackground and print the error message in onPostExcecute. The problem is I don't have the Throwable object in onPostExecute. How to catch Exception in non-UI thread and print the error message in UI-thread?
public class TestTask extends AsyncTask<Void, Void, List<String>> {
#Override
protected List<String> doInBackground(final Void... params) {
try {
...
return listOfString;
} catch(SomeCustomException e) {
...
return null;
}
}
#Override
protected void onPostExecute(final List<String> result) {
if(result == null) {
// print the error of the Throwable "e".
// The problem is I don't have the Throwable object here! So I can't check the type of exception.
}
}
}
Update after Arun's answer:
This is my AsyncTask wrapper class. It intends to do handling Exception in doInBackground but I can't find a good solution to do it.
public abstract class AbstractWorkerTask<Params, Progress, Result>
extends AsyncTask<Params, Progress, Result>
implements Workable {
protected OnPreExecuteListener onPreExecuteListener;
protected OnPostExecuteListener<Result> onPostExecuteListener;
protected ExceptionHappenedListener exceptionHappendedListener;
private boolean working;
#Override
protected void onPreExecute() {
if (onPreExecuteListener != null) {
onPreExecuteListener.onPreExecute();
}
working = true;
}
#Override
protected void onPostExecute(final Result result) {
working = false;
if(/* .........*/ ) {
exceptionHappendedListener.exceptionHappended(e);
}
if (onPostExecuteListener != null) {
onPostExecuteListener.onPostExecute(result);
}
}
#Override
public boolean isWorking() {
return working;
}
public void setOnPreExecuteListener(final OnPreExecuteListener onPreExecuteListener) {
this.onPreExecuteListener = onPreExecuteListener;
}
public void setOnPostExecuteListener(final OnPostExecuteListener<Result> onPostExecuteListener) {
this.onPostExecuteListener = onPostExecuteListener;
}
public void setExceptionHappendedListener(final ExceptionHappenedListener exceptionHappendedListener) {
this.exceptionHappendedListener = exceptionHappendedListener;
}
public interface OnPreExecuteListener {
void onPreExecute();
}
public interface OnPostExecuteListener<Result> {
void onPostExecute(final Result result);
}
public interface ExceptionHappenedListener {
void exceptionHappended(Exception e);
}
}
Change the return type of doInBackground() to Object and when you receive the result in onPostExecute(Object result) use the instanceOf operator to check if the returned result is an Exception or the List<String>.
Edit
Since the result can either be an Exception or else the proper List, you can use the following:
protected void onPostExecute(final Object result) {
working = false;
if(result instanceof SomeCustomException) {
exceptionHappendedListener.exceptionHappended(result);
}
else{
if (onPostExecuteListener != null) {
onPostExecuteListener.onPostExecute(result);
}
}
}
Also change the following statement:
public abstract class AbstractWorkerTask<Params, Progress, Object> extends AsyncTask<Params, Progress, Object>
Just store the Exception into a list and handle it later, as onPostExecute() is always called after doInBackground():
public class TestTask extends AsyncTask<Params, Progress, Result> {
List<Exception> exceptions = new ArrayList<Exception>();
#Override
protected Result doInBackground(Params... params) {
try {
...
} catch(SomeCustomException e) {
exceptions.add(e);
}
return result;
}
#Override
protected void onPostExecute(Result result) {
for (Exception e : exceptions) {
// Do whatever you want for the exception here
...
}
}
}
This is doable but rarely used, as in most situation, we want handle the exception as soon as it get thrown and catched:
public class TestTask extends AsyncTask<Params, Progress, Result> {
#Override
protected Result doInBackground(Params... params) {
try {
...
} catch(SomeCustomException e) {
// If you need update UI, simply do this:
runOnUiThread(new Runnable() {
public void run() {
// update your UI component here.
myTextView.setText("Exception!!!");
}
});
}
return result;
}
}
Hope this make sense.
Changing the return type of doInBackground to Object to possibly pass an Exception and then use instanceof() is a source of code smell (bad programming practice). It is always preferable to restrict your return type to the very specific thing you want returned.
Based on this answer simply add a private member to store the exception thrown in doInBackground and then check for it first thing in onPostExecute.
Only one Exception need be caught because you should stop the actions in doInBackground immediately once the exception is thrown and handle it gracefully in onPostExecute where you have access to the UI elements and so can inform the user of the mishap.
Generic example (body of the AsyncTask):
private Exception mException
#Override
protected Result doInBackground(Params... params) {
try {
// --- Do something --- //
}
catch( SomeException e ){ mException = e; return null; }
}
#Override
protected void onPostExecute(Result result) {
if (mException != null) {
// --- handle exception --- //
return;
}
// --- Perform normal post execution actions --- //
}

How can I call a statement after two asyncTask calls in Android?

I have a method like:
void doStuffs() {
new asyncCall1().execute();
new asyncCall2().execute();
}
How can I call another method after the two async calls have ended?
Use the get method to wait for the work to complete in a third async task:
(new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
asyncCall1.execute((Void)null);
asyncCall2.execute((Void)null);
try {
asyncCall1.get();
asyncCall2.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return (Void)null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}).execute((Void)null);
You need to invoke the method from the AsyncTask. The easiest way would be to wrap the statement in a public static method within your activity. Otherwise, you can pass the AsyncTask a reference to the activity. The classiest way to do it would be to use a Handler
Either way, your AsyncTask should go
#Override
onPostExecute(Result r)
{
//logic goes here
}
Maybe pass a Handler in to both the AsyncTasks which get called onPostExecute and build logic in to the handler :
Handler asyncTaskHandler = new Handler() {
private boolean firstTaskComplete = false;
#Override
public void handleMessage(Message msg) {
synchronized (firstTaskComplete ) {
if(!firstTaskComplete) {
firstTaskComplete = true;
} else {
// call some other code
}
}
}
};

Categories

Resources