I am an iOS developer who just recently tried Android development.
In iOS I use Completion Handlers in my codes.
I am wondering if there is an equivalent of it in Android development?
Thank you
If you need it for doing asynchronous operations then look into AsyncTask - this is a class where you implement doInBackground where your long operation is performed and onPostExecute method where code that is suppose to update UI is performed.
Now if you want to pass some special code to your AsyncTask to be performed after long operation you can:
(1) Pass an interface which would be implemented by your Activity/fragment, ex:
// Psedocode to reduce size!
interface MyInterface {
void doWork();
};
class MyAsyncTask extends AsyncTask<Void,Void,Void> {
MyInterface oper;
public MyAsyncTask(MyInterface op) { oper = op; }
// ..
public onPostExecute(Void res) {
oper.doWork(); // you could pass results here
}
}
class MyActivity extends Activity implements MyInterface {
public void doWork() {
// ...
}
public void startWork() {
// execute async on this
new MyAsyncTask(this).execute();
// or execute on anynomous interface implementation
new MyAsyncTask(new MyInterface() {
public void doWork() {
//MyActivity.this.updateUI() ...
}
});
}
};
(2) Use local broadcast receivers, EventBus, but those are more heavy weight solutions.
(3) If you already have some callback interface in you backgroung worker code then you can make it execute on UI thread using this code:
// This can be executed on back thread
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// do work on UI
}
});
Related
For my app I want to disable/change a specific button that is pressed.
I have an onclick method called btnClicked which simplified looks like this:
Public class MainActivity extends Activity{
Button myBytton;
#Override
protected void onCreate(Bundle savedInstanceState) {
myBytton = (Button)findViewById(R.id.buttonCall);
}
public void btnClicked(View view)
{
myBytton.setText("loading");
myBytton.setEnabled(false);
myBytton.setClickable(false);
// Do a call to an external api
callApi();
}
public void callApi(){
// run querys
if(succesullyCalledApi){
vibrator.vibrate(500);
// I tried commenting out the below part,
// it is than visible that the phone vibrates before it
// has changed the text (atleast a quarter of a second).
myBytton.setText("search");
myBytton.setEnabled(true);
myBytton.setClickable(true);
}
}
}
In the callApi method is a vibrate method which vibrates after the function gets a result.
Also if there is a result in the callApi myButton will be enabled and the text changed to search.
What happens is the following:
I click on the button, the phone vibrates first and afterwards it changes its text.
my question.
Why did callApi / vibrate run before myBytton.setText ?
what NigelK said is true.
When you arrive in the btnClicked method all the instructions are made on the UI thread. Therefore when you ask the System to vibrate, it will be blocked for XX time depending on the time you passed to the method vibrator.vibrate(XX);.
In order to avoid this "freeze" you need to make the vibration on another Thread.
Here is what it will look like :
Public class MainActivity extends Activity
{
Button myBytton;
#Override
protected void onCreate(Bundle savedInstanceState)
{
myBytton = (Button)findViewById(R.id.buttonCall);
}
public void btnClicked(View view)
{
myBytton.setText("loading");
myBytton.setEnabled(false);
myBytton.setClickable(false);
// Do a call to an external api
callApi();
}
public void callApi()
{
// run querys
if(succesullyCalledApi)
{
// here you create and run the Thread.
// put anything you want to do inside the run method
new Thread(
new Runnable()
{
public void run()
{
// here you start the vibration
vibrator.vibrate(500);
}
}
).start();
// I tried commenting out the below part,
// it is than visible that the phone vibrates before it
// has changed the text (atleast a quarter of a second).
myBytton.setText("search");
myBytton.setEnabled(true);
myBytton.setClickable(true);
}
}
}
And that's it. It will launch another Thread that will handle the vibration and not freeze your UI thread.
EDIT
Here is the AsyncTask version :
The three elements asked when you extend AsyncTask are :
The type of the parameters you pass to the doInBackground() method
The Type of the elements that are passed in the onProgressUpdate() method.
The Type of the element returned by the doInBackground() method that is also the parameter of the onPostExecute() method.
This is what it looks like :
public class MyTask extends AsyncTask<Void, Integer, Boolean>
{
private Button mButton;
public MyTask(Button button)
{
mButton = button;
}
// Here everything will run on a background Thread
protected Boolean doInBackground(Void... voids)
{
boolean succesullyCalledApi = false;
// do your long querys here
// ...
return succesullyCalledApi;
}
// Here everything will run on the UI Thread
protected void onProgressUpdate(Integer... progress) {
// here you can make some update to the UI like updating a
// progress bar
}
// Here everything will run on the UI Thread
protected void onPostExecute(Boolean succesullyCalledApi)
{
if(succesullyCalledApi)
{
mButton.setText("search");
mButton.setEnabled(true);
mButton.setClickable(true);
// here you start the vibration
vibrator.vibrate(500);
}
}
}
And in your callApi() method you only have to to this :
public void callApi()
{
new MyTask(myButton).execute();
}
EDIT 2
In order to retrieve the query back to your main Thread (or UI Thread) all you have to do is ... nothing.
You are in the UI Thread when the onPostExecute() method is called.
But I assume that you want to retrieve the query back to your MainActivity. To do so :
Pass MainActivity in parameter of MyTask constructor,
Create a method in MainActivity named processQuery() (or whatever you want),
Finally call this method in the onPostExecute() method.
Here are some snippets :
Public class MainActivity extends Activity
{
Button myBytton;
...
public void callApi()
{
// add this to the constructor
new MyTask(this, myButton).execute();
}
// I put String here but adapt it to your query Type.
public void processQuery(String query)
{
// process your query here.
}
}
public class MyTask extends AsyncTask<Void, Integer, Boolean>
{
private Button mButton;
private MainActivity mMainActivity;
public MyTask(MainActivity mainActivity, Button button)
{
mButton = button;
mMainActivity = mainActivity;
}
...
// Here everything will run on the UI Thread
protected void onPostExecute(Boolean succesullyCalledApi)
{
if(succesullyCalledApi)
{
// process your query
mMainActivity.processQuery("THE QUERY YOUR WANT TO PROCESS");
mButton.setText("search");
mButton.setEnabled(true);
mButton.setClickable(true);
// here you start the vibration
vibrator.vibrate(500);
}
}
}
There probably is a better way to do this but this one is simple and work :)
Hope it helps.
Cheers
This is because your call to the API is being done on the UI thread. Even though you have made changes to the UI, the screen won't refresh until the processing invoked from the button clicked event completes. Call your API on a new thread or via an Async Task to get the behaviour you want.
Because you are doing all stuff at the UI Thread. You must use an AsyncTask for your long running operations.
Try below implementation:
public void callApi() {
MyTask myTask = new MyTask();
myTask.execute();
}
private class MyTask extends AsyncTask<Void, Void, Boolean> {
protected void doInBackground(Void... params) {
// This runs on a separate background thread
boolean succesullyCalledApi = false;
// run querys
// do your long running query here and return its result.
return succesullyCalledApi;
}
protected void onPostExecute(Boolean succesullyCalledApi) {
// this runs on UI Thread
if(succesullyCalledApi){
vibrator.vibrate(500);
myBytton.setText("search");
myBytton.setEnabled(true);
myBytton.setClickable(true);
} else {
// You should better think this part also. what will happen if result is false?
}
}
}
The scenario is
I have two threads and a UI thread. The UI thread when clicked on login button creates a ClientThread which creates a socket and runs until the socket is connected, whenever a message is received i use a handler to post message to another thread called ProcessDataThread, now on receiving some messages from server i need to update UI related stuff from ProcessDataThread, I searched around alot and i found these two ways runonUiThread function which i guess can only be run from the Activity Class which is useless and the Asynctask method which i am not sure how to pass the activity context to...
Here is the code
The code executed when clicked on Login Button in the MainActivity
public void onLoginClick(View view)
{
global_constants.clientObject = new ClientThread();
global_constants.clientThread = new Thread(global_constants.clientObject);
global_constants.clientThread.start();
}
The code in ClientThread run method
public class ClientThread implements Runnable {
.......
#Override
public void run() {
......
while(!Thread.currentThread().isInterrupted() && (!CloseThread))
{
byte[] buff;
....
global_constants.updateConversationHandler.post(new ProcessDataThread(buff));
}
}
}
The method code in ProcessDataThread after parsing out the incoming data and stuff
public class ProcessDataThread implements Runnable {
.........
void ProcessLoginFailedPacket(byte[] buff)
{
// how to call the UI thread from here for updating some UI elements??
}
}
[EDIT]
i stored the activity context in a global variable and then did it this way, but i dont know whether it will be safer or not
((Activity)global_constants.MainContext).runOnUiThread(new Runnable(){
public void run()
{
TextView txtErr = (TextView) ((Activity)global_constants.MainContext).findViewById(R.id.errMsg);
txtErr.setVisibility(0);
txtErr.setText(reason);
}
});
You can post a runnable which does the UI operation to main thread as follows,
public class Utils {
public static void runOnUiThread(Runnable runnable){
final Handler UIHandler = new Handler(Looper.getMainLooper());
UIHandler .post(runnable);
}
}
Utils.runOnUiThread(new Runnable() {
#Override
public void run() {
// UI updation related code.
}
});
I have an async task that loads image urls from server.After loading urls than i load the images one by one through another asynctask.
On the click of a button i start the first asynctask
public void getit(View v)
{
new getdata().execute("http://10.0.2.2/geturls.php");
// line no 2
}
After i get the urls i use another async task to load images.
How can i find out when the image urls have been loaded and i can call the second async task at line no 2.
if i use a boolean variable which i toggle in the onpostexecute
#Override
protected void onPostExecute() {
urlgot=true;
}
then i shall have to use some repeating loop inside getit method at line no 2 to check the status of this variable urlgot. but it may take more time than allowed for ui thread.
Can there be a more cleaner method to do this check.
thanks
There are two solutions I can think of:
1) You create one AsyncTask that does everything (getting the urls, and downloading all images). Than you know exactly when to start downloading the images.
2) You start the next AsyncTask from the onPostExecute() of the first AsyncTask.
You won't be able to do your next piece of work in //line no 2 without defeating the purpose of AsyncTask. If you're doing network activity, you need to be doing it asynchronously, so that's not an option.
Instead, in onPostExecute() you can call another method in your activity that does what you would have done in //line no 2. This is safe to do, because onPostExecute() happens on the UI thread.
But depending on your design, it might make more sense to do all the //line no 2 stuff in your original AysncTask in onPostExecute, so you only have one task doing all of the work.
Use a Handler. In the method onPostExecute of your AsyncTask you can send a message informing the Handler to start another AsyncTask.
Something like this:
#Override
protected void onPostExecute(Void res) {
MyHandlerHandler handler = new MyHandlerHandler();
Message msg = new Message();
msg.what = MyHandler.TASK_FINISHED;
handler.sendMessage(msg);
}
And in your Handler class:
public class MyHandlerHandler extends Handler {
public static final int TASK_FINISHED = 2;
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TASK_FINISHED:
new MyAsyncTask().execute();
break;
}
}
}
instead of putting line 2 in getIt, put it in onPostExecute like below :
public void getit(View v)
{
new getdata().execute("http://10.0.2.2/geturls.php");
}
#Override
protected void onPostExecute() {
// line 2
}
I use a custom interface to do stuff after execution.
public Interface OnDataReceived
{
public void onReceive( Object result);
}
and on MyASyncTask
public class MyAsyncTask extends ASyncTask<Object,Object,Object>
{
OnDataReceived receiver;
public MyAsyncTask( OnDataReceived receiver )
{
this.receiver = receiver;
}
...
protected void onPostExecute( Object result)
{
receiver.onreceive( result );
}
}
and let my main class implement OnDataReceived
public class Main implements OnDataReceived
{
....
public void getit(View v)
{
new MyAsyncTask(this).execute("http://10.0.2.2/geturls.php");
}
#override
public void onReceive( Object result)
{
// do whatever
}
}
EDIT
Even for more control you can add onFailed and rename your interface to OnResponse
public Interface OnResponse
{
public void onReceive( Object result);
public void onFailed( Object errcode);
}
I create a class and extend it from view. also implemented the Runnable interface. In the onTouchEvent i call: new Thread(this).start().
This is my class:
public class test extend View interface Runnable{
----some code------
public void onTouchEvent(MotionEvent event){
----somecode------
new thread(this).start();
----somecode------
}
public void run(){
-----somecode-------
invalidate();
-----somecode-------
}
}
but i receive this error:
only the original thread that created a view hierarchy can touch its views
How can i fix this?
Try to use
postInvalidate()
instead of
invalidate()
you need to update UI on UIThread, use
Activity activity = (Activity)getContext();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// update UI here
invalidate();
}
});
You can use handler class to make changes on your UI thread by sending messages.
http://developer.android.com/reference/android/os/Handler.html
Android, Handler messaging
Since you are extending View class which binds to UI-thread, so anything you call in this class will run on the UI-thread. However, if you are using a new thread inside that class, then you may rely on its post(Runnable) method which will guarantee to run on the view's UI-thread. For example:
post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
}
});
this will run on UI thread from View class;
post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
}
});
Try AsyncTask in android. It start new thread asynchronously and after completion of task it can update current UI without destroying current Activity.
Example Code :
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
// Task which should be completed in background.
return null;
}
protected void onProgressUpdate(Integer... progress) {
// Task which can be done while background process is progressing , such as updatng any UI element of Activity.
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
// Task to do after completion of asynctask.
showDialog("Downloaded " + result + " bytes");
}
}
You may also use runOnUiThread to do your task.
Both ways are very effective in updating UI in current activity.
Useful Link : http://developer.android.com/reference/android/os/AsyncTask.html
http://sharecoding.wordpress.com/2012/05/22/simple-runonuithread-for-update-view-on-android/
I have a very simple AsyncTask implementation example and am having problem in testing it using Android JUnit framework.
It works just fine when I instantiate and execute it in normal application.
However when it's executed from any of Android Testing framework classes (i.e. AndroidTestCase, ActivityUnitTestCase, ActivityInstrumentationTestCase2 etc) it behaves strangely:
It executes doInBackground() method correctly
However it doesn't invokes any of its notification methods (onPostExecute(), onProgressUpdate(), etc) -- just silently ignores them without showing any errors.
This is very simple AsyncTask example:
package kroz.andcookbook.threads.asynctask;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.Toast;
public class AsyncTaskDemo extends AsyncTask<Integer, Integer, String> {
AsyncTaskDemoActivity _parentActivity;
int _counter;
int _maxCount;
public AsyncTaskDemo(AsyncTaskDemoActivity asyncTaskDemoActivity) {
_parentActivity = asyncTaskDemoActivity;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
_parentActivity._progressBar.setVisibility(ProgressBar.VISIBLE);
_parentActivity._progressBar.invalidate();
}
#Override
protected String doInBackground(Integer... params) {
_maxCount = params[0];
for (_counter = 0; _counter <= _maxCount; _counter++) {
try {
Thread.sleep(1000);
publishProgress(_counter);
} catch (InterruptedException e) {
// Ignore
}
}
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int progress = values[0];
String progressStr = "Counting " + progress + " out of " + _maxCount;
_parentActivity._textView.setText(progressStr);
_parentActivity._textView.invalidate();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
_parentActivity._progressBar.setVisibility(ProgressBar.INVISIBLE);
_parentActivity._progressBar.invalidate();
}
#Override
protected void onCancelled() {
super.onCancelled();
_parentActivity._textView.setText("Request to cancel AsyncTask");
}
}
This is a test case. Here AsyncTaskDemoActivity is a very simple Activity providing UI for testing AsyncTask in mode:
package kroz.andcookbook.test.threads.asynctask;
import java.util.concurrent.ExecutionException;
import kroz.andcookbook.R;
import kroz.andcookbook.threads.asynctask.AsyncTaskDemo;
import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity;
import android.content.Intent;
import android.test.ActivityUnitTestCase;
import android.widget.Button;
public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> {
AsyncTaskDemo _atask;
private Intent _startIntent;
public AsyncTaskDemoTest2() {
super(AsyncTaskDemoActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
_startIntent = new Intent(Intent.ACTION_MAIN);
}
protected void tearDown() throws Exception {
super.tearDown();
}
public final void testExecute() {
startActivity(_startIntent, null, null);
Button btnStart = (Button) getActivity().findViewById(R.id.Button01);
btnStart.performClick();
assertNotNull(getActivity());
}
}
All this code is working just fine, except the fact that AsyncTask doesn't invoke it's notification methods when executed by within Android Testing Framework. Any ideas?
I met a similar problem while implementing some unit-test. I had to test some service which worked with Executors, and I needed to have my service callbacks sync-ed with the test methods from my ApplicationTestCase classes. Usually the test method itself finished before the callback would be accessed, so the data sent via the callbacks would not be tested. Tried applying the #UiThreadTest bust still didn't work.
I found the following method, which worked, and I still use it. I simply use CountDownLatch signal objects to implement the wait-notify (you can use synchronized(lock){... lock.notify();}, however this results in ugly code) mechanism.
public void testSomething(){
final CountDownLatch signal = new CountDownLatch(1);
Service.doSomething(new Callback() {
#Override
public void onResponse(){
// test response data
// assertEquals(..
// assertTrue(..
// etc
signal.countDown();// notify the count down latch
}
});
signal.await();// wait for callback
}
I found a lot of close answers but none of them put all the parts together correctly. So this is one correct implementation when using an android.os.AsyncTask in your JUnit tests cases.
/**
* This demonstrates how to test AsyncTasks in android JUnit. Below I used
* an in line implementation of a asyncTask, but in real life you would want
* to replace that with some task in your application.
* #throws Throwable
*/
public void testSomeAsynTask () throws Throwable {
// create a signal to let us know when our task is done.
final CountDownLatch signal = new CountDownLatch(1);
/* Just create an in line implementation of an asynctask. Note this
* would normally not be done, and is just here for completeness.
* You would just use the task you want to unit test in your project.
*/
final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() {
#Override
protected String doInBackground(String... arg0) {
//Do something meaningful.
return "something happened!";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
/* This is the key, normally you would use some type of listener
* to notify your activity that the async call was finished.
*
* In your test method you would subscribe to that and signal
* from there instead.
*/
signal.countDown();
}
};
// Execute the async task on the UI thread! THIS IS KEY!
runTestOnUiThread(new Runnable() {
#Override
public void run() {
myTask.execute("Do something");
}
});
/* The testing thread will wait here until the UI thread releases it
* above with the countDown() or 30 seconds passes and it times out.
*/
signal.await(30, TimeUnit.SECONDS);
// The task is done, and now you can assert some things!
assertTrue("Happiness", true);
}
The way to deal with this is to run any code that invokes an AsyncTask in runTestOnUiThread():
public final void testExecute() {
startActivity(_startIntent, null, null);
runTestOnUiThread(new Runnable() {
public void run() {
Button btnStart = (Button) getActivity().findViewById(R.id.Button01);
btnStart.performClick();
}
});
assertNotNull(getActivity());
// To wait for the AsyncTask to complete, you can safely call get() from the test thread
getActivity()._myAsyncTask.get();
assertTrue(asyncTaskRanCorrectly());
}
By default junit runs tests in a separate thread than the main application UI. AsyncTask's documentation says that the task instance and the call to execute() must be on the main UI thread; this is because AsyncTask depends on the main thread's Looper and MessageQueue for its internal handler to work properly.
NOTE:
I previously recommended using #UiThreadTest as a decorator on the test method to force the test to run on the main thread, but this isn't quite right for testing an AsyncTask because while your test method is running on the main thread no messages are processed on the main MessageQueue — including the messages the AsyncTask sends about its progress, causing your test to hang.
If you don't mind executing the AsyncTask in the caller thread (should be fine in case of Unit testing), you can use an Executor in the current thread as described in https://stackoverflow.com/a/6583868/1266123
public class CurrentThreadExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}
And then you run your AsyncTask in your unit test like this
myAsyncTask.executeOnExecutor(new CurrentThreadExecutor(), testParam);
This is only working for HoneyComb and higher.
I wrote enough unitests for Android and just want to share how to do that.
First off, here is helper class that responsible to wait and release waiter. Nothing special:
SyncronizeTalker
public class SyncronizeTalker {
public void doWait(long l){
synchronized(this){
try {
this.wait(l);
} catch(InterruptedException e) {
}
}
}
public void doNotify() {
synchronized(this) {
this.notify();
}
}
public void doWait() {
synchronized(this){
try {
this.wait();
} catch(InterruptedException e) {
}
}
}
}
Next, lets create interface with one method that should be called from AsyncTask when work is done. Sure we also want to test our results:
TestTaskItf
public interface TestTaskItf {
public void onDone(ArrayList<Integer> list); // dummy data
}
Next lets create some skeleton of our Task that we gonna test:
public class SomeTask extends AsyncTask<Void, Void, SomeItem> {
private ArrayList<Integer> data = new ArrayList<Integer>();
private WmTestTaskItf mInter = null;// for tests only
public WmBuildGroupsTask(Context context, WmTestTaskItf inter) {
super();
this.mContext = context;
this.mInter = inter;
}
#Override
protected SomeItem doInBackground(Void... params) { /* .... job ... */}
#Override
protected void onPostExecute(SomeItem item) {
// ....
if(this.mInter != null){ // aka test mode
this.mInter.onDone(data); // tell to unitest that we finished
}
}
}
At last - our unitest class:
TestBuildGroupTask
public class TestBuildGroupTask extends AndroidTestCase implements WmTestTaskItf{
private SyncronizeTalker async = null;
public void setUP() throws Exception{
super.setUp();
}
public void tearDown() throws Exception{
super.tearDown();
}
public void test____Run(){
mContext = getContext();
assertNotNull(mContext);
async = new SyncronizeTalker();
WmTestTaskItf me = this;
SomeTask task = new SomeTask(mContext, me);
task.execute();
async.doWait(); // <--- wait till "async.doNotify()" is called
}
#Override
public void onDone(ArrayList<Integer> list) {
assertNotNull(list);
// run other validations here
async.doNotify(); // release "async.doWait()" (on this step the unitest is finished)
}
}
That's all.
Hope it will help to someone.
This can be used if you want to test the result from the doInBackground method. Override the onPostExecute method and perform the tests there. To wait for the AsyncTask to complete use CountDownLatch. The latch.await() waits till the countdown runs from 1 (which is set during initialization) to 0 (which is done by the countdown() method).
#RunWith(AndroidJUnit4.class)
public class EndpointsAsyncTaskTest {
Context context;
#Test
public void testVerifyJoke() throws InterruptedException {
assertTrue(true);
final CountDownLatch latch = new CountDownLatch(1);
context = InstrumentationRegistry.getContext();
EndpointsAsyncTask testTask = new EndpointsAsyncTask() {
#Override
protected void onPostExecute(String result) {
assertNotNull(result);
if (result != null){
assertTrue(result.length() > 0);
latch.countDown();
}
}
};
testTask.execute(context);
latch.await();
}
How about using join?
fun myTest() = runBlocking {
CoroutineScope(Dispatchers.IO).launch {
// test something here
}.join()
}
Use this simple solution
runBlocking{
//Your code here
}
Most of those solutions require a lot of code to be written for every test or to change your class structure. Which I find very difficult to use if you have many situations under test or many AsyncTasks on your project.
There is a library which eases the process of testing AsyncTask. Example:
#Test
public void makeGETRequest(){
...
myAsyncTaskInstance.execute(...);
AsyncTaskTest.build(myAsyncTaskInstance).
run(new AsyncTest() {
#Override
public void test(Object result) {
Assert.assertEquals(200, (Integer)result);
}
});
}
}
Basically, it runs your AsyncTask and test the result it returns after the postComplete() has been called.